javascript - 为何会报错呢,
大家讲道理
大家讲道理 2017-04-11 13:18:29
[JavaScript讨论组]


说getSuperValue is not a function。麻烦指点下,谢谢

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(4)
PHP中文网
因为此时的instance.__proto__和SubType.prototype指向两个不同的对象。

这里需要注意的是我们通常认为instance.__proto__==SubType.prototype//true,是因为他们的值相同,即他们保存的对象指针相同。当一个函数被创建是内存就会有一块区域作为原型对象,在函数中prototype属性指向它,在函数的实例对象中[prototype](也就是我们常用的__proto__,注:这是浏览器方便测试引入的并不是规范属性)指向它。为SubType.prototype直接赋值会使他它的变量值也就是对象指针发生变化,SubType.prototype会指向一个全新的对象。但原来的原型对象并没有销毁,在生成实例时[prototype]还是会指向它。

你可以在你的代码后加console.log(instance.__proto__==SubType.prototype)加以验证,注释掉SubType.prototype返回true,不注销返回false。
到这里应该清楚了,如果还有疑问可以查阅《权威指南》原型部分或《js高程》构造函数部分。
希望对你有所帮助
ringa_lee

虽然 已经完结了,但是我还是想补上一份我的答案。

题主的希望 :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的时候

  1. var o = new Object();

  2. o.__proto__ = A.prototype; 绑定原型

  3. A.call(o); 绑定this, 并执行构造函数里面的代码

  4. 把这个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的引用地址改变而改变

PHPz


我来搬运一下,看了应该很明白了,为什么写在外面就可以,写在里面就不可以。
另外推荐看这个blog
写的挺不错的,不过要很好的理解还是要不断的写代码实践。

ringa_lee

原型对象才有原型,实例没有原型。

SubType.prototype = new SuperType();

你在这里把SubType的原型赋值成了一个实例,而一个对象的实例本身是没有原型的方法的,它是基于__proto__属性往原型链上去找的。

而由于你给SubType.prototype赋值的不是一个原型对象,所以实际上原型链在这里已经断掉了,所以也不可能找到那个函数。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号