我已经阅读了几篇关于js继承的文章(this one,this one,this one等。)
在Mozilla的this article中,“经典”继承如下所示:(我统一化的例子)
// inherit Base
function Derived() { ... }
Derived.prototype = new Base(); <-------
Derived.prototype.constructor = Derived; <-------
但是在this article我看到了:
// inherit Base
function Derived() { ... }
Derived.prototype = Object.create(Base.prototype); <-------
Derived.prototype.constructor = Derived;
此外我也看到了这个:
Derived.prototype = Base.prototype;
我也进行了实验,但未能找到constructor
做作的用法:
Derived.prototype.constructor = Derived; <--- it still work if I skip this line
如果我跳过此行,new Derived()
无论如何都会正确调用Derived()
。
所以1)什么是正确的:
Derived.prototype = new Base();
Derived.prototype = Object.create(Base.prototype);
Derived.prototype = Base.prototype;
而且2)真的需要Derived.prototype.constructor = Derived;
吗?为什么?
答案 0 :(得分:3)
Derived.prototype = new Base();
这只是为了设置原型链而调用Base
构造函数。虽然有时候工作并给予Object.create
相同的结果,但它容易出错,应该避免。阅读What is the reason to use the 'new' keyword at Derived.prototype = new Base(以及不的原因)。
Derived.prototype = Object.create(Base.prototype);
这是最先进的 - Correct javascript inheritance可以说。
Derived.prototype = Base.prototype;
This is plain wrong。 Do not use。它允许Base
和Derived
实例从相同的对象继承 - 而它(很少)可以帮助为“类”提供多个构造函数,这不是“子类化” ”
真的需要
Derived.prototype.constructor = Derived;
吗?为什么呢?
它可以省略,但你的脚本仍然可以工作,但为方便起见,你会期望(new Derived).constructor === Derived
。另请查看JavaScript inheritance and the constructor property
答案 1 :(得分:1)
在JavaScript中进行经典继承的正确方法是什么
在this回答中,我解释了1和2之间的区别,说明为什么2是在JavaScript中模拟经典继承的最佳方式。
简而言之,在解决方案1中,子级继承自父级的实例。在解决方案2中,子类(Derived.prototype)继承自父类(Base.prototype)的类。这对父类施加了严格的限制,因为必须使用0参数调用它。
第三种解决方案更糟糕,因为Derived和Base类的原型是同一个对象,因此不能进行任何方法覆盖。更糟糕的是,Derived.prototype中定义的方法将可用于所有Base实例,如果在Base.prototype上声明了具有相同名称的方法,则只需替换它。
结论:2是在JavaScript中进行经典继承的真正方法。
设置所需的构造函数属性
在原型上设置constructor
属性使其可供所有实例访问。这只是为了方便,继承部分在没有它的情况下工作。