javascript - 一道关于原型的问题
天蓬老师
天蓬老师 2017-04-11 11:52:35
[JavaScript讨论组]
var fun = function(){}

fun.prototype = {    
    name : 'peter',    
    age : 25    
}

var a = new fun();
var b = new fun();
console.log(a.name, b.name);//peter peter
fun.prototype.name = 'jack';
console.log(a.name, b.name);//jack jack
fun.prototype = {};
fun.prototype.name = 'tom';
console.log(a.name, b.name);//jack jack
b.constructor.prototype.name = 'kitty';
console.log(a.name, b.name);//jack jack
//输出些什么鬼?

fun.prototype = {};
fun.prototype.name = 'tom';

操作之后的输出很不理解,fun的prototype已经改变了,访问a的name属性,查找原型链不应该输出tom?
更新:
还有一个问题,由于fun.prototype = {}操作覆盖了原型,所以之后对fun.prototype的属性修改其实修改的是{}.于是把fun.prototype = {}操作去掉,代码如下:

var fun = function(){}

fun.prototype = {    
    name : 'peter',    
    age : 25    
}

var a = new fun();
var b = new fun();
console.log(a.name, b.name);//peter peter
fun.prototype.name = 'jack';
console.log(a.name, b.name);//jack jack
fun.prototype.name = 'tom';
console.log(a.name, b.name);//tom tom
b.constructor.prototype.name = 'kitty';
console.log(a.name, b.name);//tom tom
//输出些什么鬼?

b.constructor.prototype.name = 'kitty'这一步问什么没有生效呢

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(6)
ringa_lee

你要知道一点,Object的赋值,其实都是引用。就懂了。

你可以试一下给出现过的object命名。

fun.prototype = {    
    name : 'peter',    
    age : 25    
} //A

所以a和b的 proto 指向 A

fun.prototype.name = 'jack';
此时fun.prototype也指向A,所以是A的name被修改了。

fun.prototype = {};//B
此时fun.prototype指向B

然而a,b依然指向A。

这里体现的其实是Object的引用性质

巴扎黑

对于更新中:

b.constructor.prototype.name = 'kitty'这一步问什么没有生效呢

答案:

更改:

fun.prototype = {    
    name : 'peter',    
    age : 25    
}

为:

fun.prototype = {    
    constructor: fun,
    name : 'peter',    
    age : 25    
}

因为你给 prototype 赋值了一个新的对象的引用,所以原来的原型链被切断了。默认情况下 fun.prototype.constructor 的值为 fun

怪我咯

1).prototype ={}是重写原型,重写后跟重写前就已经实例化的对象没有关系的,所以Tom自然不生效。
2)但你之前实例化的对象的constructor仍然是Fun,Fun的prototype.name=“Kitty”相当于你把name属性添加到重写后的原型里,由于1)的原因自然不生效咯。

阿神

对象在创建的时候原型链就已经定下来了,

fun.prototype={};
fun.prototype.name='tom';

这时候fun.prototype是一个新的对象,而a和b的__proto__依旧是之前的fun.prototype所以输出的就是jack。
如果你在后边在后边在新实例化出一个对象,这个新的对象中的属性就会继承自新的原型中的属性了

var c=new fun();
console.log(c.name)//tom
黄舟

这种吗?应该是b指向的原来的原型

PHP中文网

其实这个很简单
1.fun.prototype={},原型链是引用的,之后切断了,之后的设置肯定不行
2.吧fun.prototype={}去掉后,为什么b.constructor.prototype.name = 'kitty'这句话不起作用,那是因为b.constructor != fun. 而设置原型链,只能设置fun.prototype或者设置a.__proto__等,只要能把值设置在原型链上,都是没有问题的,通过引用原理,就能赋值

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

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