说getSuperValue is not a function。麻烦指点下,谢谢
虽然 已经完结了,但是我还是想补上一份我的答案。
题主的希望 :instance.__proto__ = new SuperType();
实际的情况 :instance.__proto__ = SubType.oldPrototype;
function SuperType() {
this.property = true;
SuperType.prototype.getSuperValue = function () {
return this.property;
}
}
function SubType() {
this.prototype = false;
SubType.prototype = new SuperType(); //1
}
SubType.prototype.old = 'oldPrototype'; //oldPrototype
var instance = new SubType();
console.log(instance.old);
console.log(instance.getSuperValue());
因为在new的时候
var o = new Object();
o.__proto__ = A.prototype; 绑定原型
A.call(o); 绑定this, 并执行构造函数里面的代码
把这个o返回给a;//完成var a = new A()的过程.
由上面看出
我们的原型在 构造函数内的函数运行时已经完成了绑定。
这也是如果我们写在外面为什么会生效的原因。
但是这里还需要注意一个问题:
SubType.prototype = new SuperType();
这句话 改变了原型的引用地址,如果在构造函数中写上这句话,就会造成instance的实例已经附上SubType.prototype,而不是这个new SuperType(); 此时intance不会因为你对Subtype.prototype而改变,因为instance.__proto__的引用的是oldPrototype的内存地址。
如果你再加一段代码
var instance2 = new SubType();
console.log(instance2.getSuperValue());
这个时候 你就可以输出,这个时候原型链就是正常的,因为已经改变过一次。!~!~
重点就是:1. new做了什么,2. 对prototype的直接赋值对象会造成引用地址改变 3.instance.__proto__的引用地址不会跟着prototype的引用地址改变而改变
原型对象才有原型,实例没有原型。
SubType.prototype = new SuperType();
你在这里把SubType的原型赋值成了一个实例,而一个对象的实例本身是没有原型的方法的,它是基于__proto__属性往原型链上去找的。
而由于你给SubType.prototype赋值的不是一个原型对象,所以实际上原型链在这里已经断掉了,所以也不可能找到那个函数。
8 回答5.8k 阅读✓ 已解决
9 回答9.2k 阅读
6 回答4.7k 阅读✓ 已解决
5 回答3.5k 阅读✓ 已解决
4 回答7.9k 阅读✓ 已解决
7 回答9.8k 阅读
5 回答7.1k 阅读✓ 已解决
这里需要注意的是我们通常认为instance.__proto__==SubType.prototype//true,是因为他们的值相同,即他们保存的对象指针相同。当一个函数被创建是内存就会有一块区域作为原型对象,在函数中prototype属性指向它,在函数的实例对象中[prototype](也就是我们常用的__proto__,注:这是浏览器方便测试引入的并不是规范属性)指向它。为SubType.prototype直接赋值会使他它的变量值也就是对象指针发生变化,SubType.prototype会指向一个全新的对象。但原来的原型对象并没有销毁,在生成实例时[prototype]还是会指向它。