【发布时间】:2015-05-22 16:47:09
【问题描述】:
JS对象模型一定有什么我不明白的地方。
来自这些资源:
我收集了我认为或认为是对象模型的准确心理表示。这里是:
所有对象都有一个属性,文档将其称为[[Prototype]]。 [[Prototype]] 可以被认为是对对象父级的引用。更准确地说:
对 [parent's] 原型对象的引用被复制到 新实例的内部
[[Prototype]]属性。 (source 1)
您可以使用Object.getPrototypeOf(child) 访问子级的[[Prototype]] 属性,此处返回的值将是对父级原型的引用(不是其内部[[Prototype]] 属性,而是其实际原型)
obj.prototype 不同于对象的内部[[Prototype]] 属性。它的作用类似于用于制作此精确对象实例的蓝图,而其[[Prototype]] 属性指向用于制作其父对象实例的蓝图。
Parent.prototype === Object.getPrototypeOf(child); //true
详细说明:
如果您向
child.prototype添加一个函数,该函数将对child及其任何子级可用。如果向
parent.prototype添加一个函数,相当于向Object.getPrototypeOf(child)添加一个函数,那么该函数将对parent及其所有子项可用,包括child和它的所有siblings。
您可以使用Object.create() 来创建一个具有您想要的任何[[Protoype]] 属性的新对象。因此,您可以将其用作实现继承的一种方式。示例见source 2。
考虑到这一点,我想获得一个我自己的工作示例。我的计划是创建一个父“类”,然后创建一个继承自它的子“类”。
我希望子类实现一个方法,该方法重载了父类的方法。需要注意的是,我希望子版本的方法调用父版本的方法,然后做一些额外的事情。
这是我想出的,请参阅下面的相关问题:
var Parent = function() {};
Parent.prototype.myF = function() {
console.log('derp');
};
function Child() {
Parent.call(this);
};
//make [[prototype]] of Child be a ref to Parent.prototype
Child.prototype = Object.create(Parent.prototype);
//need to explicitly set the constructor
Child.prototype.constructor = Child;
Child.prototype.myF = function() {
Object.getPrototypeOf(this).myF();
console.log("did I derp??");
};
childInstance = new Child();
childInstance.myF();
似乎是这样的,当我尝试重载Parent.myF() 时,在重载它的同时,我实际上是在修改原始函数。似乎是这种情况,因为记录的结果是:
'derp'
'did I derp??'
'did I derp??'
大概'did I derp??' 的第一次出现来自父函数的修改版本,我不是的意思,那么第二个版本来自子函数。
谁能详细说明为什么会这样?
【问题讨论】:
-
问题写得非常好。
-
确认 OP 在 chrome 中的输出,与 firefox 相同。 @Ankit:您是否在 Mozilla Firefox 开发版中检查了右侧的红色“2”? prntscr.com/78578d
-
您的理解有一处错误。
obj.prototype不是一回事。只有函数具有.prototype属性。对象具有.constructor属性。所以真的是obj.constructor.prototype。 -
[[Prototype]] can be thought of as a reference to the object's parent- 实际上,父原型是原型链的一部分,当调用子函数时会检查该原型链。所有祖先的原型都构成了这条链的一部分,一直追溯到根Object。因此,如果对child.Foo()的调用没有调用子实例或子原型上的任何内容,则解释器将检查parent.prototype.Foo(),如果存在,将调用它。如果不存在,我们将检查grandParent.prototype.Foo()等... -
@LukeP 原型继承是关于扩充的。看这一行:
Child.prototype = Object.create(Parent.prototype);通过这样做,您已经引入了所有父原型的方法,但是您通过添加myF()扩展了子原型的方法。这不是在引用父原型,而是在扩展它。
标签: javascript oop inheritance prototype