深入解析 JavaScript 中 prototype 与 __proto__ 的关系与区别
本文详细解析 JavaScript 中 prototype 与 __proto__ 的核心概念及相互关系。通过对比分析,阐明 prototype 是构造函数指向原型对象的指针,而 __proto__ 是实例指向构造函数的原型链路径。结合代码示例说明原型链的查找机制、constructor 属性的作用以及函数作为对象时的特殊性,帮助开发者理清对象继承与属性共享的底层逻辑。
prototype 属性的定义与作用
在 JavaScript 中,每个函数都拥有一个名为 prototype 的属性,该属性指向一个对象,即原型对象。这个原型对象的用途在于存储可以被特定类型的所有实例共享的属性和方法。值得注意的是,原型对象内部还包含一个指向另一个对象的属性,这构成了原型链的基础结构。
__proto__ 与原型链机制
Function 本身也是一个对象,因此它既拥有 prototype 属性,也拥有所有对象共有的 __proto__ 属性。__proto__ 被称为隐式原型,它是对象内部初始化的一个属性,用于指向构造该对象的构造函数的原型。当访问一个对象的属性时,若该对象内部不存在该属性,JavaScript 引擎会沿着 __proto__ 指向的原型对象继续查找。由于原型对象自身也有 __proto__,这种层层递进的查找机制构成了原型链。通过 __proto__,实例能够访问在构造函数原型中定义的属性和方法。
函数对象的特殊性:prototype 与 constructor
Function 作为一种特殊对象,除了具备通用的 __proto__ 属性外,还拥有特有的 prototype 属性。prototype 是一个指针,指向一个用于包含所有实例共享属性和方法的对象,即原型对象。由构造函数创建的对象实例,其原型指向该构造函数的 prototype。使用原型对象的主要优势在于实现属性和方法的共享,避免在构造函数内部重复定义实例信息,只需将共享内容添加到原型对象即可。此外,原型对象包含一个 constructor 属性,该属性是一个指针,指回原始的构造函数。
prototype 与 __proto__ 的联系
prototype 与 __proto__ 之间存在紧密的联系,二者均指向原型对象。
prototype 和 __proto__ 都指向原型对象。任意一个函数(包括构造函数)都有一个 prototype 属性,指向该函数的原型对象。同样,任意一个由构造函数实例化的对象,都有一个 __proto__ 属性(该属性并非标准属性,ECMA-262 第5版将其称为 [[Prototype]],可通过 Object.getPrototypeOf() 标准方法访问),它指向构造函数的原型对象。
prototype 与 __proto__ 的区别
prototype 与 __proto__ 存在显著区别。
代码示例:原型关系验证
//a作为构造函数时的prototype属性与a作为普通函数时的__proto__属性并不相等
console.log(a.prototype == a.__proto__);//false
console.log(a.__proto__); //function (){}
console.log(a.__proto__ == Function.prototype);//true
//a作为一个普通函数调用时,它的构造函数是内置对象Function,所以它指向的原型对象,就是Function.prototype.
//其实这个和console.log(b.__proto__ == a.prototype)是一样的道理
//a作为构造函数时,它的原型,和它的原型的原型
console.log(a.prototype); //a{}
console.log(a.prototype.__proto__); //Object{}
//a作为普通函数时,它原型的原型
console.log(a.__proto__.__proto__); //Object{}
console.log(a.__proto__.__proto__ == a.prototype.__proto__); //true
所有对象都拥有 __proto__ 属性,而函数这一特殊对象除了 __proto__ 外,还特有 prototype 属性。prototype 对象默认包含 constructor 和 __proto__ 两个属性。prototype 属性用于给函数和对象添加可共享(继承)的属性和方法,而 __proto__ 则是查找函数或对象原型链的路径。constructor 属性包含一个指针,指回原构造函数。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
为什么JS中typeof []返回object:数组类型检测误区解析
2026-11-04 19:50:47
D3.js 新手入门:环境搭建与第一个条形图实现
2026-11-04 10:49:48
