关于 “JavaScript重写原型对象后设置constructor” 的误解

首先我们要知道prototype、constructor及其关系:

每个函数都有 prototype属性(即原型对象)
原型对象都有 constructor属性(指针):它指向着该原型对象的拥有者。
现在看下面例子:

function Child() {}
Child.prototype = {};   //重写prototype
Child.prototype.constructor = Child;
1
2
3
误解:
之所以执行Child.prototype.constructor = Child,是因为:
我们重写了Child的prototype,导致prototype的constructor指向发生了改变,因而要让其指向正确的位置。

正解:
之所以执行Child.prototype.constructor = Child,是因为:
constructor是原型对象特有的属性,所以在我们将一个空对象赋给了prototype后,prototype对象压根就没有constructor属性(都没有,谈何改变呢?)
执行第三句仅仅是为了为prototype增加constructor属性,并规定其正确的指向。

如果在没有执行Child.prototype.constructor = Child的情况下,强行访问constructor,那访问的便是其 父级原型(沿着原型链找)的constructor所指向的值:

function Child2() {}
Child2.prototype = {};   //重写prototype
console.log(Child2.prototype.constructor);     //ƒ Object() { [native code] }
1
2
3
在Child2.prototype没有constructor属性的前提下, 又要得到Child2.prototype.constructor的值,那只好沿着原型链找,看看它的父级(Object)有没有constructor属性,发现:“啊有!!”
所以Child2.prototype.constructor的值为 ƒ Object() { [native code] },即指向Object()


总结:
只有prototype才有constructor属性,而其他实例对象没有。(不考虑继承)
若完全重写prototype,需要为重写后的prototype增加constructor属性,并规定其正确的指向。
我们再看一个例子:

function Parent () {
    this.name = 'bty';
}
function Child () {}
1
2
3
4
(1)我们再执行:

console.log(new Parent());
console.log(Child.prototype);
1
2
在控制台输出:

我们看到此时Parent构造函数new出的实例没有constructor属性(不考虑继承),而Child.prototype有。
这也印证了上面的话:只有prototype才有constructor属性,而其他实例对象没有(不考虑继承)

(2)再接着,我们让Child继承Parent,并打印Child的原型对象:

Child.prototype = new Parent();
console.log(Child.prototype);
1
2
在控制台输出:

和new Parent()的输出结果一模一样,没有constructor属性。

(3)继续,我们为Child.prototype添加constructor属性并规定其指向,然后再打印Child的原型对象:

Child.prototype.constructor = Child;
console.log(Child.prototype);
1
2
控制台输出:


添加成功,Child.prototype的constructor指向Child

实现继承时为何总是要修正constructor的指向呢?

在知乎的一篇问答中看到一种说法:

constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。
 ———————————————— 
版权声明:本文为CSDN博主「我叫白天宇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/b954960630/article/details/84997144

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值