较新的 JavaScript (ES6) 和 TypeScript 中原型/基于原型的继承的最佳实践?

彼得·T。

这里有几个较旧的问题,讨论 Javascript 原型继承和委托,例如:

我想知道当前(2018 年)的建议是在 Javascript 中使用原型/原型继承。

据我所知,较新版本的 JavaScript (ES6) 和 TypeScript 都更倾向于传统的基于类的继承。(我自己在实践中还没有使用 ES6 或 TS。)这个观察是真的吗?

其实这段基于类的代码真的很简单易懂:

class A { a: "a" }
class B extends A { b: "b" }
let a = new A(), b = new B();

编辑 2:在 TypeScript 中,它将是:

class A { a = "a" }
class B extends A { b = "b" }
let a = new A(), b = new B();

编辑:事实上,ES6 语法更复杂:

class A { constructor() { this.a = "a"; } }
class B extends A { constructor() { super(); b = "b"; } }
let a = new A(), b = new B();

对于使用prototypes,有更多的选择,实际上我还没有找到一个同样简单和“好”的。

编辑我想要实现的是,我使用原型 A 创建 b 作为 B 的实例,这样当我动态更改 A 的属性时, b 也会受到更改的影响:

一个简单的方法是:

var A = { a: "a" }
var B = Object.create(A, {b: {value: "b"}});
var a = Object.create(A), // direct instance of A
    b = Object.create(B); // indirect instance of A
console.log(b.a); // "a"
A.a = "a++"; // change the base prototype (will affect B, a, and b)
console.log(b.a); // "a++"

如果第二个 arg 也可以是具有键值对的简单对象,而不是属性描述符,那会好得多(请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ Global_Objects/对象/创建)

大多数情况下,使用构造函数,例如在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

function A() { this.a = "a"; }
function B() { this.b = "b"; }
B.prototype = new A();
var a = new A(), b = new B();
console.log(b.a); // "a"
A.a = "a++";
console.log(b.a); // return "a" instead of "a++" as b.a is overwritten in constructor

此外,不太好,因为在这里你不能以 ba 也改变的方式改变 Aa,这是 IMO 原型继承中的一个关键点。所以也许这个?

function A() {}
A.prototype.a = "a";
function B() {}
B.prototype = Object.create(A.prototype);
B.prototype.b = "b";
var a = new A(), b = new B();
function A() { this.a = "a"; }
function B() { this.b = "b"; }
B.prototype = new A();
var a = new A(), b = new B();
console.log(b.a); // "a"
A.a = "a++";
console.log(b.a); // still "a" instead of "a++"

没有给出预期的结果。而且,好吧,你不想写这个,对吧?

当然,您可以按照https://stackoverflow.com/a/16872315/1480587所述将创建放在构造函数中,但我认为这对于类语法来说仍然不够好和简单。实际上,我正在寻找这样的东西(类似于Kotlin 的对象声明):

object A { a: "a" }
object B extends A { b: "b" }
let a = new A(), b = new B();

那么,你会推荐什么?有什么可以接近的吗?

特别是,如果您想使用一些封装并且让私有对象成员对克隆对象不可见?

TypeScript 在这里提供了一个很好的解决方案吗?

去 Kotlin 吗?

还是应该回到基于类的继承,因为这是其他人都在使用和理解的?

彼得·T。

我刚刚找到了我要找的东西:在 ES6 中,“对象文字被扩展为支持在构造时设置原型。” 真的很简单方便!!

var obj = {
    // Sets the prototype. "__proto__" or '__proto__' would also work.
    __proto__: theProtoObj,
    // Computed property name does not set prototype or trigger early error for
    // duplicate __proto__ properties.
    ['__proto__']: somethingElse,
    // ...
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章