JavaScript原型链详解:prototype与__proto__的区别与联系

作者:纸飞机

时间:2026-10-22

浏览:424

本文详细解析JavaScript中prototype与__proto__的核心概念。通过构造函数、原型对象及实例之间的关系,阐明prototype指向原型对象,而__proto__指向构造函数的原型。文章结合代码示例,厘清两者在原型链查找机制中的不同作用,帮助开发者准确理解对象继承与属性共享机制。

文章目录

JavaScript原型链详解:prototype与__proto__的关系

前言

在学习原型机制时,许多开发者容易感到困惑,尤其是面对prototype和__proto__这两个概念时,往往难以区分。经过查阅相关资料并结合个人理解,现将核心要点梳理如下:

一、构造函数基础

一、构造函数基础

所谓构造函数,是指利用new关键字来创建特定类型对象的函数。例如Object和Array属于内置的原生构造函数,它们在运行时会自动加载到执行环境中,开发者可直接调用。具体示例如下:


var arr = new Array();//使用Array构造函数创建了一个array实例arr
arr[0]="a";
arr[1]="b";
alert(arr);//a,b

var obj=new Object();//使用Object构造函数创建了一个Object实例obj
obj.name="c";
obj.age=12;
alert(obj.name);//c

开发者也可以自定义构造函数,并为其添加自定义的属性和方法,例如:


//创建构造函数Person
function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 alert(this.name)//
 };
}

//使用new关键字,来生成Person实例
var person1=new Person("Tom",22);
var person2=new Person("Jerry",21);
person1.sayName();//Tom
person2.sayName();//Jerry

在使用构造函数时,需注意以下几点:

  • 1. 构造函数的命名通常以大写字母开头,这主要是为了与普通函数区分开来。
  • 2. 构造函数本质上也是函数,其定义语法与普通函数完全一致。两者的区别在于调用方式:只要使用new操作符调用,该函数即可作为构造函数;若不使用new直接调用,则视为普通函数。

function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 alert(this.name)//
 };
}

//当做构造函数使用
var person=new Person("Tom",22);
person.sayName();//Tom 
//当做普通函数使用
Person("Jerry",30);//添加到window
sayName();//Jerry 等同于window.sayName();

二、原型对象(Prototype)

二、原型对象(Prototype)

每个函数都拥有一个prototype属性,该属性是一个指向原型对象的指针。原型对象在函数定义时同步创建,其主要作用是存储所有实例共享的属性和方法。


function Person(){
}
//自定义原型对象的属性和方法
Person.prototype.name="Tom";
Person.prototype.age=25;
Person.prototype.sayName=function(){
 alert(this.name);
};
//原型对象中的所有属性和方法 都会自动被所有实例所共享
var person1=new Person();
var person2=new Person();
person1.sayName();//Tom
person2.sayName();//Tom

每当创建一个新函数,该函数会自动获得一个prototype属性,指向其原型对象(原型对象在定义时同步创建)。此原型对象包含一个名为constructor的属性,反向指向函数本身,从而形成一种循环引用关系。

例如在前述示例中:alert(Person.prototype.constructor===Person);//会返回true


function Person(){}
alert(Person.prototype.constructor===Person);//true

三、__proto__属性解析

三、__proto__属性(注意两侧各有两个下划线)

当通过构造函数创建新实例后,该实例内部会包含一个指针[[Prototype]],指向创建它的构造函数的原型。尽管脚本标准中没有直接访问[[Prototype]]的方法,但大多数浏览器支持通过__proto__属性进行访问。


function Person(){
}
//自定义原型对象的属性和方法
Person.prototype.name="Tom";
Person.prototype.age=25;
Person.prototype.sayName=function(){
 alert(this.name);
};
//原型对象中的所有属性和方法 都会自动被所有实例所共享
var person1=new Person();
var person2=new Person();
person1.sayName();//Tom
person2.sayName();//Tom
alert(person1.__proto__===Person.prototype);//true

以前述示例代码为例,各对象间的关系如下图所示:

 JavaScript原型链详解:prototype与__proto__的关系

总结:

① 只要创建了函数,其对应的原型对象便会同时生成。原型对象中的属性和方法,会被该构造函数创建的所有实例所共享。

② 每个函数在创建后都会获得一个prototype属性,该属性指向该函数的原型对象。

③ 每个对象的__proto__属性都指向其构造函数的原型。

以上即为关于JavaScript中prototype与__proto__关系的完整解析,希望本文内容能对您的学习或工作有所帮助。如有疑问,欢迎留言交流,感谢支持。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章