JavaScript原型链详解

作者:代码拾荒时间:2026-10-24 18:09:19浏览:420

本文详细解析JavaScript中的原型链机制,涵盖构造函数与实例的关系、prototype与__proto__属性的区别与联系,以及Function和Object原型的特殊指向。通过代码示例说明实例如何访问共享属性,并梳理原型链终点为null的完整逻辑,帮助开发者深入理解JS面向对象的核心原理。

1、构造函数与实例化

若定义一个名为Foo()的函数,即可通过new Foo()操作来创建其实例对象。


    function Foo() {
      console.log("我是一个构造方法");
    }
    const f1 = new Foo();

此时可明确Foo()为构造函数,而f1为其对应的实例。

2、Prototype属性解析

Foo()在此处被视为一个函数定义。

函数在JavaScript中属于对象类型,因此函数本质上也是对象。

既然对象具备属性,函数便拥有一个独特的属性prototype,普通对象并不具备此属性。

该属性指向一个原型对象(即Foo.prototype),且该原型对象内部包含一个名为constructor的属性,该属性持有指向原构造函数的指针。

 


   function Foo() {
      console.log("我是一个构造方法");
    }
    const f1 = new Foo();

    console.log(Foo.prototype);//Foo的原型对象
    console.log(f1.prototype);//f1没有 underfied


1、构造函数与实例化

3、__proto__属性机制

前文提及的prototype旨在为构造函数的所有实例提供共享的方法与属性。

实例对象如何访问这些共享资源呢?

实例f1自身不包含prototype,但拥有所有对象共有的__proto__,属性,该属性指向创建该实例的构造函数的原型对象,JavaScript语言正是依据此属性实现实例对共享属性和方法的访问。

鉴于Foo是f1的构造函数,Foo.prototype即为Foo的原型对象,因此f1.__proto__指向Foo.prototype。


    function Foo() {
      console.log("我是一个构造方法");
    }

    const f1 = new Foo();

    console.log(Foo.prototype);
    console.log(f1.__proto__);


1、构造函数与实例化

4、访问原型上的方法

若构造函数Foo希望其所有实例共享某一属性(如name),则需将该属性定义在Foo的原型对象上。

 


   function Foo() {
      console.log("我是一个方法");
    }

    Foo.prototype.name = "我是Foo创造的实例共享的属性";

    const f1 = new Foo();
    const f2 = new Foo();

    console.log(f1.name);//我是Foo创造的实例共享的属性
    console.log(f2.name);//我是Foo创造的实例共享的属性


1、构造函数与实例化

5、构造函数自身的__proto__

前文指出所有对象均具备__proto__ 属性,由于Foo既是函数也是对象,那么Foo.__proto__的值为何?

需追溯Foo的构造函数,作为函数,Foo由JavaScript内置构造函数Function创建,该内置构造函数的Function.prototype为所有JS中创建的函数提供内置的公共方法与属性。

因此,Foo.__proto__指向Funtion.prototype。

6、构造函数原型的__proto__

Foo.prototype同样属于对象,故其也具备__proto__。属性。

查找__proto__,时需追溯其构造函数,Foo.prototype为纯对象,其构造函数为Object,故Object的原型为Object.prototype。。

由此可知,Foo.prototype.__proto__指向Object.prototype。

7、Object.prototype的特殊性

Array、String、Funtion、Object均为函数, 它们均为Function构造函数的实例, Array.__proto__、String.__proto__、Funtion.__proto__ 、Object.__proto__均指向Funtion.prototype原型, 从而可调用Funtion.prototype原型中的公共方法, 例如均可通过.name属性查看函数名称。

Array.prototype、String.prototype、Funtion.prototype这些原型对象均为对象, 它们均为Object构造函数的实例, Array.prototype.__proto__ 、String.prototype.__proto__、Funtion.prototype.__proto__均指向Object.prototype原型, 故可调用Object.prototype原型对象的公共方法。

而Object.prototype较为特殊,虽为对象,却非Object自身的实例, Object.prototype.__proto__指向null,作为原型链的终点。

8、总结

函数(即方法)拥有prototype属性,即方法的原型。 实例通常对应一个构造函数,实例的__proto__指向该构造函数的原型。 JavaScript内置多种构造函数,如Array、String、Funtion、Object,分别对应不同对象类型,其原型上封装了常用方法。 所有构造函数本身为函数,是内置构造函数Funtion的实例。 除Object.prototype外,所有构造函数的原型均为对象,是内置构造函数Object的实例。 Object.prototype.__prototype指向null,作为原型链终点。

1、构造函数与实例化

至此,关于JavaScript原型链的详细解析结束,更多相关内容请参阅本站往期文章或继续浏览后续文章,感谢支持!

作者最新文章