发布网友 发布时间:2024-10-24 01:02
共1个回答
热心网友 时间:2024-11-07 07:20
一.原型修改
先看这个例子
functionPerson(name){this.name=name}varp=newPerson('River')//修改原型Person.prototype.getName=function(){console.log('你好,我是',this.name)}执行p.getName(),控制台打印:
此时,p的constructor是Person,p的__proto__指向构造函数Person的prototype
console.log(p.constructor===Person)//trueconsole.log(p.__proto__===Person.prototype)//true二.原型重写而原型重写,结果可能和我们预想的不一样
值得注意的constructor属性1.例子1functionPerson(name){this.name=name}Person.prototype={getName:function(){console.log('你好,我是',this.name)}}varp=newPerson('River')执行p.getName(),控制台打印:
此时,p的constructor是Object,而p的__proto__指向Person的prototype
console.log(p.constructor===Object)//trueconsole.log(p.constructor===Person)//falseconsole.log(p.__proto__===Object.prototype)//falseconsole.log(p.__proto__===Person.prototype)//true2.为什么?首先我们需要明确一点,当我们new一个新对象的时候,会有以下几个步骤:
创建临时对象
绑定原型,让临时对象的__proto__指向函数的prototype
将函数的this指向该对象,执行构造函数
如果没有其他返回对象,就自动返回这个对象
注意,在我们重写原型prototype的时候,使用对象字面量的方式创建了一个新的对象,而且没有定义constructor
所以在new的过程中,构造函数是缺失的,按照原型链的查找规则,当前层级找不到就会继续向上查找,Person的prototype作为一个对象,它的__proto__指向Object.prototype:
当然了,Object的constructor还是Object
所以p.constructor===Object
当然也有其他值得注意的点,比如重写原型后的Person的__proto__指向依旧为Function.prototype,Person的constructor为Function。
3.例子2:实例在前,重写在后为了更加彻底的了解重写原型,我们再来举一个例子,先声明实例p,再重写Person:
functionPerson(name){this.name=name}varp=newPerson('River')Person.prototype={getName:function(){console.log('你好,我是',this.name)}}执行p.getName(),控制台打印:
可以看到,p的__proto__指向的是重写前的Person.prototype,是调用不到重写后的getName的
自然,constructor也不会改变
避免constructor的指向问题1.修改prototype,而不是重写参上
2.自己给constructor赋值还是拿上面的例子来说,可以在重写的时候手动给constructor赋值,重定指向
functionPerson(name){this.name=name}Person.prototype={constructor:Person,getName:function(){console.log('你好,我是',this.name)}}varp=newPerson('River')三.总结在重写原型时,会产生constructor丢失的现象,使新建的实例.constructor===Object。我们在重写原型链的时候应当注意到这个问题,可以通过手动给constructor赋值来重定指向。
原文:https://juejin.cn/post/7101934229314863118