JavaScript 原型与原型链核心机制解析

作者:闭包旅人

时间:2026-10-29

浏览:82

本文详细解析 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 原型概念概述

原型链结构图

原型链的形成机制

原型链 由于每个对象和原型都拥有原型,对象的原型指向原型对象,而父对象的原型又指向父对象的原型,这种层层连接的原型关系构成了原型链。

属性查找规则

一、属性查找 当查找一个对象的属性时,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”,这表明对象的构建方式会影响原型链的形式。

JavaScript 原型概念概述

{}对象原型链结构图

原型机制核心总结

综图所述 1. 所有的对象都有__proto__属性,该属性对应该对象的原型. 2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对3. 象的_proto_属性. 4. 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数. 5. 函数对象和原型对象通过prototype和constructor属性进行相互关联.

以上即为关于 JS 原型、原型链的详细内容介绍,希望对大家的学习有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章