JavaScript-原型链

111 阅读3分钟

原型链


概念:

原型链是一种机制,指的是JavaScript每个对象包括原型对象都有一个内置的__proto__属性(是从构造函数的prototype属性派生的)指向创建它的函数对象的原型对象,即prototype属性。在对象实例和它的构造器之间建立一个链接,之后通过上溯原型链,在构造器中找到这些属性和方法

原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

作用:

原型链的存在,主要是为了实现对象的继承。(或者理解成引用)

理解:

在这里插入图片描述

  • 函数对象: 在JavaScript中,函数即对象。

  • 原型对象(prototype): 当定义一个函数对象的时候,会包含一个预定义的属性,叫prototype,这就属性称之为原型对象。

//函数对象
function Person(){};
Person.prototype

在这里插入图片描述

//普通对象
var person = {};
person.prototype	//undefined

在这里插入图片描述

  • _proto_: JavaScript在创建对象的时候,都会有一个_proto_的内置属性,用于指向创建它的函数对象的prototype。原型对象也有_proto_属性。因此在不断的指向中,形成了原型链。
//函数对象
function Person(){};
Person.prototype = {
    say: function(){}
};
var person = new Person();
person.__proto__

在这里插入图片描述

  • new:
function Person(){};
var person = new Person();

当使用new去调用构造函数时,相当于执行了如下操作

var person = {};
person.__proto__ = Person.prototype;
Person.call(person);

因此,在原型链的实现上,new起到了很关键的作用。

  • constructor: 原型对象prototype上都有个预定义的constructor属性,用来引用它的函数对象。这是一种循环引用。
function Person(){};
Person.prototype.constructor === Person;

在这里插入图片描述

例子:
function Person(name) {
    this.name = name;
    this.age = 18;
    this.say = function() {
        console.log(this.name);
    }
}
// 第二步 创建实例
var person = new Person('person')

大概的关系图:

在这里插入图片描述

分析:

  • 构造函数 Person存在原型对象 Person.prototype ;

  • 构造函数生成实例对象person,person的__proto__指向构造函数Person原型对象(Person.prototype);

  • Person.prototype.proto 指向内置对象(即 Object.prototype),因为 Person.prototype 是个对象,默认是由 Object函数作为类创建的,而 Object.prototype 为内置对象;

  • Person.proto 指向内置匿名函数 anonymous,因为 Person 是个函数对象,默认由 Function 作为类创建;

  • Function.prototype 和 Function.__proto__同时指向内置匿名函数 anonymous,这样原型链的终点就是 null。

总结:

概念: __proto__作为不同对象之间的桥梁,指向创建它的构造函数 的原型对象。

在这里插入图片描述

每个对象的__proto__都是指向它的构造函数的原型对象( prototype )

person1.__proto__ === Person.prototype

构造函数是一个函数对象,是通过 Function构造器产生的

Person.__proto__ === Function.prototype

原型对象本身是一个普通对象,而普通对象的构造函数都是Object

Person.prototype.__proto__ === Object.prototype

所有的构造器都是函数对象,函数对象都是 Function构造产生的

Object.__proto__ === Function.prototype

Object的原型对象也有__proto__属性指向null,null是原型链的顶端

Object.prototype.__proto__ === null

总言之:
  • 一切对象都是继承自Object对象,Object 对象直接继承根源对象null。

  • 一切的函数对象(包括 Object 对象),都是继承自 Function 对象。

  • Object 对象直接继承自 Function 对象。

  • Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象。