You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS原型属性疑问:修改p1.y后为何p2.y仍为200而非201?

为什么修改p1.y后p2.y没变化?

嘿,这个问题戳中了JavaScript原型链里一个很容易踩坑的点——属性遮蔽(Shadowing),我给你一步步拆解清楚:

首先先把你的代码贴出来方便对照:

function person(){ this.x = 100; }
person.prototype.y = 200;
var p1 = new person();
var p2 = new person();
++p1.y;
console.log(p1.y); // 输出201
console.log(p2.y); // 输出200

核心逻辑拆解

  1. 初始状态:你把y=200挂在了person的原型对象上,这时候p1和p2这两个实例本身并没有自己的y属性——它们访问y的时候,是顺着原型链“往上找”,找到原型上的那个公共的y。

  2. 执行++p1.y的本质:这个操作是「读→改→存」的三步组合:

    • 第一步:读取p1.y,此时因为p1自己没有y,所以找到原型上的200;
    • 第二步:把200加1变成201;
    • 第三步:重点来了!JavaScript不会直接去修改原型上的那个公共y,而是会在p1这个实例对象上新建一个属于它自己的y属性,把201存进去。这就叫“属性遮蔽”——实例自己的属性会遮蔽原型上的同名属性。
  3. 后续访问差异:

    • 再访问p1.y时,JS会优先取实例自己的y(也就是201),不会再去原型找了;
    • 而p2从来没被修改过y,它自己还是没有y属性,所以依然去原型上取那个没被改动过的200。

验证这个逻辑

你可以加几行代码验证我说的:

console.log(p1.hasOwnProperty('y')); // 输出true,说明p1现在有自己的y属性
console.log(p2.hasOwnProperty('y')); // 输出false,p2还是没有自己的y
console.log(person.prototype.y);     // 输出200!原型上的y根本没被碰过

如果真的想修改原型上的y,让所有实例都看到变化,你得直接操作原型:

person.prototype.y++; // 直接改原型的y
console.log(p1.y); // 201
console.log(p2.y); // 201

内容的提问来源于stack exchange,提问作者Jagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:03:17