JS构造函数原型问题

function Person() {}

Person.prototype.name = 'Nicholas';

const p1 = new Person();

console.log(p1.name); // Nicholas

p1.name = 'Greg';

console.log(p1.__proto__.name); // Nicholas

// 为什么上面输出不是 'Greg'

代码如上。name属性是在构造函数Person的原型上的。当我实例化p1时,修改了name的值,因为p1实例本身没有name属性,所以就会去原型上找。而p1实例对原型是一种引用,所以按照正常逻辑,不应该原型上的name属性也会被修改吗?

阅读 2.6k
3 个回答

1、

p1.name = 'Greg';

重点是这句代码,他不会修改原型的 name ,而是直接设置 实例 的 name,不管原型上有没有,如果实例上有 name 就覆盖,没有就设置;

2、如果你单独访问属性:

p1.name

这样,在实例上没有 name 属性时,才会去原型链上找;

3、

p1实例对原型是一种引用

错误,Object.getPrototypeOf(p1)p1.constructor.prototype才是对 p1 原型的引用

4、不要用 __proto__ 属性,如果要访问实例的原型用 Object.getPrototypeOf 设置原型用 Object.setPrototypeOf

p1实例对原型是一种引用这句有误

p1是Person的实例,他有个__proto__属性指向/引用Person的原型

p1.name是修改或访问他本身的name属性,访问他的属性或方法时,如果它本身没有,会去原型链上找

p1.__proto__.name是修改或访问原型的name属性

构造函数实例化的时候,会从原型链上继承属性,这个继承是通过指针指向原型对象所在内存。
实例化后创建的对象单独占用一个内存,当更改属性的时候,会在对象内添加一个属性,你可以通过hasOwnProperty检查是继承的属性还是自身有的属性。如下代码:

function Func(){}
Func.prototype.name="nihao";
var abc=new Func();
console.log(abc.name);
console.log(abc.hasOwnProperty("name"));
abc.name="text";
console.log(abc.name);
console.log(abc.hasOwnProperty("name"));
// 打印abc对象的结构,看的更清楚些
console.dir(abc);

如上,name属性是在实例化后的对象上的,所以,修改name值,并不会导致原型链上name值的改变。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题