JavaScript 原型链与属性遮蔽机制解析

作者:闭包旅人

时间:2026-10-25

浏览:342

本文通过一道JavaScript面试题,深入剖析原型链中属性读取与赋值的区别。当调用修改原型属性的方法时,若该属性不存在于实例,赋值操作会在实例上创建新属性,从而形成“属性遮蔽”。文章结合代码示例,解释了为何不同实例的计数结果不同,并演示如何使用hasOwnProperty验证属性归属。

文章目录

JavaScript 原型链与属性遮蔽机制解析

相关代码如下所示:

 
var Fundamental = {count:1};
function Test(){}
Test.prototype = Fundamental;
Test.prototype.increase = function(){this.count++;};
var test = new Test();
console.log(test.count);
var test2 = new Test();
console.log(test2.count);
test.increase();
//test.count和test2.count的值各是多少

面试题场景与代码示例

这是前天面试中遇到的一道题目,面试官主要询问当执行test.increase后,test和test2对象的count属性值分别是多少。


在解答此题前,需要区分一种容易混淆的类似场景:


如果将代码结构修改为以下形式:


相关代码如下所示:

 
function FundamentalModified(){
var count = 1;
this.increase = function(){
count++;
} 
this.show = function(){
return count;
} 
} 
function TestModified(){}
TestModified.prototype = new FundamentalModified();
var test3 = new TestModified();
var test4 = new TestModified();
test3.increase();
//test3.show()和test4.show()各是多少

易混淆场景对比

若问题转化为上述形式,解答将变得简单许多。但需注意,这两种情况下的执行结果并不相同。


==========================================分割一下


属性遮蔽原理与验证

回到原题,正确答案是test.count为2,test2.count为1。其核心原因在于:test.count是test实例自身的属性,而test2.count实际上是通过原型链访问Test.prototype中的count属性。

当执行test.increase()时,JavaScript引擎执行了this.count++操作,即返回this.count并执行this.count = this.count + 1。

this.count = this.count + 1;

这句看似简单的代码,实际上蕴含了重要的语义差异。

其实际含义是:为实例对象新建一个名为count的属性,并将其值赋为this.count + 1。

这里的this.count在读取时,由于实例本身没有count属性,因此会沿原型链查找Test.prototype.count。

因此,在第一次执行increase时,实际表现为:this.count = Test.prototype.count + 1。

可以使用hasOwnProperty方法来验证这一过程:

当执行var test = new Test()时,test.hasOwnProperty("count")返回false; 执行test.increase()后,test.hasOwnProperty("count")返回true。 总体而言,JavaScript的语言机制确实充满趣味。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章