JavaScript 原型与原型链核心机制解析
本文详细解析 JavaScript 中的原型与原型链机制,阐明 prototype 与 __proto__ 的区别,以及 new 运算符的执行步骤。通过 Object 和 Function 对象的特殊性分析,结合属性查找规则与不同创建方式对原型链的影响,帮助开发者彻底理解对象继承与属性访问原理。
JavaScript 原型概念概述
原型是 JavaScript 中一个相对抽象的概念,涉及多个相关属性。具体而言,普通对象拥有“prototype”属性(注:此处原文表述可能有误,通常指实例对象的内部原型引用),函数对象拥有“prototype”属性,而原型对象则包含“constructor”属性。
初识原型与内部属性
一、初识原型 在 JavaScript 中,原型本质上也是一个对象,它支持对象的属性继承。JavaScript 中的每个对象都包含一个名为“[[Prototype]]”的内部属性,该属性指向对象的原型。 由于“[[Prototype]]”是内部属性,无法直接访问。为了便于调试,Firefox 和 Chrome 等浏览器提供了非标准的访问器“__proto__”(并非所有浏览器都支持)。此外,ECMA 标准引入了“Object.getPrototypeOf(object)”作为标准的原型访问方法。在 JavaScript 的原型对象中,还包含一个“constructor”属性,该属性指向创建所有指向该原型的实例的构造函数。
原型规则与函数属性
二、规则 在 JavaScript 中,每个函数都具备一个“prototype”属性。当一个函数被用作构造函数来创建实例时,该函数的“prototype”属性值会被赋值给所有生成的对象实例(即设置实例的“__proto__”属性)。这意味着,所有实例的原型引用均指向该函数的“prototype”属性。(注意:只有函数对象才拥有此属性!)
new 运算符的执行步骤
new 的过程分为三步
var p = new Person('张三',20);
1. var p={}; 初始化一个空对象 p。 2. p._proto_=Person.prototype;,将对象 p 的“__proto__”属性设置为 Person.prototype。 3. Person.call(p,”张三”,20); 调用构造函数 Person 来初始化 p。关于 call/apply 使用
Object 与 Function 原型分析
三、初识Object Object 对象本身是一个函数对象。(CODE TEST) 既然 Object 是函数,它必然拥有“prototype”属性,因此“Object.prototype”的值即为“Object {}”这个原型对象。反之,当访问“Object.prototype”对象的“constructor”属性时,即可得到 Object 函数。 此外,通过“Object.prototype._proto_”获取 Object 原型的原型时,结果为“null”。这表明“Object {}”原型对象是原型链的终点。 四、初识Function 如前文示例中的构造函数所示,JavaScript 中的函数也是对象,因此可以通过“__proto__”查找构造函数对象的原型。 Function 对象作为一个函数,拥有“prototype”属性,该属性对应“function () {}”对象。 Function 对象作为一个普通对象,拥有“__proto__”属性,该属性对应“Function.prototype”,即满足“Function._proto_ === Function.prototype”。
prototype 与 __proto__ 的区别
在此对“prototype”和“__proto__”进行简要区分: 对于所有对象,均存在“__proto__”属性,该属性指向该对象的原型。 对于函数对象,除“__proto__”外,还具备“prototype”属性。当函数作为构造函数创建实例时,该函数的“prototype”属性值将被赋值给所有对象实例(即设置实例的“__proto__”属性)。

原型链结构图
原型链的形成机制
原型链 由于每个对象和原型都拥有原型,对象的原型指向原型对象,而父对象的原型又指向父对象的原型,这种层层连接的原型关系构成了原型链。
属性查找规则
一、属性查找 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到指定名称的属性为止。若遍历至原型链顶部(即 Object.prototype)仍未找到指定属性,则返回 undefined。
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.MaxNumber = 9999;
Person.__proto__.MinNumber = -9999;
var will = new Person("Will", 28);
console.log(will.MaxNumber); // 9999
console.log(will.MinNumber); // undefined
原型属性添加示例
在此示例中,分别给“Person.prototype”和“Person.__proto__”这两个原型对象添加了“MaxNumber”和“MinNumber”属性,这需要明确“prototype”和“__proto__”的区别。
“Person.prototype”对应由 Person 构造函数创建的所有实例的原型,即“Person.prototype”属于这些实例原型链的一部分。因此,当这些实例进行属性查找时,会引用到“Person.prototype”中的属性。
对象创建方式对原型链的影响
对象创建方式影响原型链
var July = {
name: "张三",
age: 28,
getInfo: function(){
console.log(this.name + " is " + this.age + " years old");
}
}
console.log(July.getInfo());
当使用这种方式创建一个对象时,原型链结构如下所示。July 对象的原型是“Object.prototype”,这表明对象的构建方式会影响原型链的形式。

{}对象原型链结构图
原型机制核心总结
综图所述 1. 所有的对象都有__proto__属性,该属性对应该对象的原型. 2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对3. 象的_proto_属性. 4. 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数. 5. 函数对象和原型对象通过prototype和constructor属性进行相互关联.
以上即为关于 JS 原型、原型链的详细内容介绍,希望对大家的学习有所帮助。
什么时候该用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
