JavaScript 原型链与属性遮蔽机制解析
本文通过一道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的语言机制确实充满趣味。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
