JavaScript原型链误区:prototype与__proto__的区别
本文澄清JavaScript原型继承中的常见误区,指出函数对象的prototype属性不参与自身标识符查找,真正参与查找的是__proto__。通过代码示例说明Foo.label与foo.label的差异,以及Function.prototype.forEach对Object.forEach的影响,帮助开发者准确理解原型链机制。
JavaScript原型链误区:prototype与__proto__的区别
过去我对JavaScript原型链中,原型继承与标识符查找的机制存在困惑。
例如,观察以下代码行为:
代码如下:
function Foo() {};
var foo = new Foo();
Foo.prototype.label = "laruence";
alert(foo.label); //输出: laruence
alert(Foo.label);//输出: undefined
今天看到一张示意图:

另外,在Javascript Object Hierarchy文档中提到:
The prototype is only used for properties inherited by objects/instances created by that function. The function itself does not use the associated prototype.
这意味着,函数对象的prototype属性并不参与该函数自身的原型链查找过程。
今天在Firefox浏览器下发现(因为Firefox通过__proto__暴露了[[prototype]]内部属性),真正参与标识符查找的是函数对象的__proto__属性。
代码如下:
function Foo() {};
var foo = new Foo();
Foo.__proto__.label = "laruence";
alert(Foo.label); //输出: laruence
alert(foo.label);//输出: undefined
显然:
代码如下:
function Foo() {};
alert(Foo.__proto__ === Foo.prototype); //输出: false
此外,这也解释了:
代码如下:
alert(Object.forEach); // undefined
Function.prototype.forEach = function(object, block, context) {
for (var key in object) {
if (typeof this.prototype[key] == "undefined") {
block.call(context, object[key], key, object);
}
}
};
alert(Object.forEach);
alert(Function.forEach);
alert(Object.forEach === Function.forEach); // trueJavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
