图解JavaScript原型(prototype)与原型链机制
本文深入解析JavaScript中原型(prototype)与原型链的核心机制。通过图解方式说明构造函数、原型对象与实例之间的__proto__指向关系,阐述属性与方法查找的就近原则,并揭示原型链如何使自定义对象继承Object内置方法,实现实例间的属性共享。
原型与原型链基础概念
利用原型方式,我们解决了多个实例间方法共享的问题。接下来,我们将深入剖析原型(prototype)与原型链的具体运作机制。
function CreateObj(uName) {
this.userName = uName;
}
CreateObj.prototype.showUserName = function(){
return this.userName;
}
var obj1 = new CreateObj('ghostwu');
var obj2 = new CreateObj('卫庄');

首先,每个函数都拥有一个名为 prototype 的属性。该属性是一个指针,指向构造函数的原型对象(例如 CreateObj.prototype),如图中第1条绿色箭头所示。
其次,默认情况下,所有原型对象都会自动获得一个 constructor 属性。该属性的作用在于指向定义该 prototype 属性的函数,如图中第2条绿色箭头所示。
第三,所有通过构造函数使用 new 创建的实例(包括原型对象如 CreateObj.prototype,尽管图中暂未画出),都包含一个隐式原型属性 __proto__。该指针指向实例所属构造函数的原型对象。
如图中第3条和第4条箭头所示,obj1 的构造函数是 CreateObj,其原型对象为 CreateObj.prototype;obj2 同理。因此:
obj1.__proto__ === CreateObj.prototype //true
obj2.__proto__ === CreateObj.prototype //true
第四,在构造函数内部通过 this 赋值的属性和方法,在绘制对象模型时,应将其画在具体的实例对象上。例如 userName 是赋予对象的属性,因此 obj1 和 obj2 这两个实例对象上都会存在 userName 属性。
第五,定义在原型对象上的方法或属性,在绘制模型时应将其画在原型对象上。例如:
CreateObj.prototype.showUserName = function(){
return this.userName;
}
showUserName 方法应当绘制在图中的 CreateObj.prototype 上。
第六,当对象访问属性或方法时,遵循“就近原则”,具体规则如下:
如果实例上存在该属性或方法,则直接使用实例上的值。
如果实例上不存在该属性或方法,则沿着实例的 __proto__ 指针指向的原型对象继续向上查找;若仍找不到,则返回 undefined。
console.log( obj1.showUserName() ); //ghostwu
console.log( obj2.showUserName() ); //卫庄
在 obj1 和 obj2 上并不存在 showUserName 方法,因此会顺着 __proto__ 查找至 CreateObj.prototype 原型对象上的 showUserName 方法。
如果将 CreateObj.prototype 原型对象上的 showUserName 方法注释掉,那么 obj1.showUserName 和 obj2.showUserName 将会报错。
// CreateObj.prototype.showUserName = function(){
// return this.userName;
// }
function CreateObj(uName) {
this.userName = uName;
this.showUserName = function(){
return '100';
}
}
CreateObj.prototype.showUserName = function(){
return this.userName;
}
var obj1 = new CreateObj('ghostwu');
var obj2 = new CreateObj('卫庄');
console.log( obj1.showUserName() ); //100
console.log( obj2.showUserName() ); //100
如果在构造函数内部为 this 添加一个 showUserName 方法,那么 obj1 和 obj2 将直接调用 this 上的方法。因为这两个方法被绘制在实例上,所以:
console.log( obj1.showUserName === obj2.showUserName ); //false
现在,你应该能明白,将属性和方法写在构造函数的原型对象(prototype)上后,能够实现多个实例属性和方法共享的原理了吧。
原型链的构成与查找机制
什么是原型链?
前文提到,所有实例(包括原型对象)都有一个隐式原型 __proto__。那么,CreateObj.prototype 这个原型对象的 __proto__ 指向哪里呢?
function CreateObj(uName) {
this.userName = uName;
this.showUserName = function () {
return '100';
}
}
CreateObj.prototype.showUserName = function () {
return this.userName;
}
console.log( CreateObj.prototype.__proto__ ); //指向Object.prototype
console.log( CreateObj.prototype.__proto__ === Object.prototype ); //true

CreateObj.prototype.__proto__ 指向的是 Object.prototype,通过全等运算符(===)测试结果为 true。
Object.prototype.__proto__ 指向的是 NULL。
这就是原型链,它通过隐式原型将各个构造函数层层串联起来。通过上述图示,我们可以理解为什么自定义对象能够调用 toString、valueOf 等方法。
因为所有对象最终都继承自 Object。
以上这篇[js高手之路]图解javascript的原型(prototype)对象,原型链实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
JS对象数组转字符串为什么推荐用JSON.stringify()
2026-11-05 09:40:31
