使用继承时,ChildObject.prototype = new ParentObject();
或ChildObject.prototype = ParentObject.prototype;
之间的差异和方法会更好。
我在Douglas Crockford的例子中看过ChildObject.prototype = new ParentObject();
。
答案 0 :(得分:4)
。
相反:
ChildObject.prototype = Object.create(ParentObject.prototype);
ChildObject.prototype.constructor = ChildObject;
在ChildObject
:
ParentObject.call(this/*, appropriate args if any*/);
或者如果传递所有 args:
ParentObject.apply(this, arguments); // `arguments` literally -- it's provided by the JavaScript engine
ChildObject.prototype = new ParentObject();
的问题是,如果ParentObject
需要参数,它将无效,就像许多(大多数?)构造函数一样。因此,该模式不适用于常见(可能是多数)的情况。
ChildObject.prototype = ParentObject.prototype;
的问题在于,你们两个都指向同一个对象。因此,在ChildObject.prototype
上设置属性会使其显示在ParentObject
的实例上(因为您刚刚将其设置在ParentObject.prototype
上)。
Object.create
版本推迟调用ParentObject
,直到您有一个初始化对象,但为您提供了一个对象,您可以在该对象上放置特定于ChildObject
实例的内容。 (constructor
反向链接是为了使替换对象看起来像默认的ChildObject
原来的那个;这在过去并不重要,但在某些情况下它实际上是由ES6使用的,有些是libs之前使用它,即使ES5和之前没有[他们只是把它放在那里]。)
最后:Object.create
的单参数版本可以在2009年之前在ES5中添加时为过时的浏览器填充,或者如果你不喜欢部分填充的东西,你可以使用工厂函数:
function objectCreate(proto) {
function ctor() { }
ctor.prototype = proto;
return new ctor;
}
答案 1 :(得分:3)
我们通常使用原型来提供方法 - 避免为每个类实例复制相同的函数。换句话说,对于类似......的事情。
ChildObject.prototype.foo = function() {
console.log('foo');
};
现在您可能会看到第二种方法的问题:修改ChildObject.prototype
也会修改ParentObject.prototype
(它是ChildObject.prototype = ParentObject.prototype
行之后的同一个对象)。这意味着此示例中的所有ParentObject
都可以使用foo
方法。实际上,说ParentObject
是ChildObject
的父是不正确的 - 两者都有相同的原型链。
然而,另一个令人讨厌的副作用。考虑一下:
function ParentObj() {}
function ChildObj() {}
ChildObj.prototype = ParentObj.prototype;
var i = new ParentObj();
console.log(i); // ParentObj {}
var j = new ChildObj();
console.log(j); // ParentObj {}
请参阅两个原型,因为它们是同一个对象,具有相同的constructor
属性。因此,为了区分这些,我们必须在构造函数中引入一些标志,基本上覆盖已有的机制。
答案 2 :(得分:2)
如果你这样做
ChildObject.prototype = ParentObject.prototype;
然后您的父母和孩子拥有相同的原型。有了后者,
ChildObject.prototype = new ParentObject();
孩子的原型是父母本身。