一次搞懂原型修改与重写

发布网友 发布时间:2024-10-24 01:02

我来回答

1个回答

热心网友 时间:2024-10-24 02:35

一.原型修改

先看这个例子

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

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com