js 原型链

97 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

前言

JS 中原型是比较难理解的知识点。其涉及的属性比较多,有_proto__,prototype,[[prototype]],constructor等相关的属性内容。

原型链

JS 中没有类的的概念,但在里面所有的类型都可以称为对象,比如字符串、数组、函数都可以说是对象。JS 中实现继承主要通过原型链实现的。基本思想就是通过原型继承多个引用类型的属性和方法。

所有的对象都有_proto_ 访问器属性(getter 和 setter)。可以使用 Object.getPrototypeof方法来获取 _proto_ 指向的对象。

  • 原型:对象的 _proto_ 属性或者是函数的 prototype 属性所指向的对象
  • 原型对象:构造函数的 prototype 属性所指的对象。
  • 每个构造函数都有一个原型对象,原型有一个属性指向构造函数,而实例有一个内部指针指向原型。所以原型链就是实例和原型之间构造的原型链。

对象 proto

function Person(name) {
  this.name = name;
  this.age =18;
  this.sayHello = function(){
    console.log(this.name)
  }
}

var person = new Person('Tommy')

在控制台上输出以下创建的 person 对象:

Person 构造函数的原型对象 Person.prototype。输出的实例对象 person的 _proto_ 指向构造函数 Person 原型对象 prototype。person._proto_ === Person.prototype

构造函数是由 Function 构造器产生的是,所以构造函数的原型对象是指向 Function的原型对象 prototype。 Person.proto===Function.prototype

原型对象 prototype 本身也是对象。所指向的是Object的原型对象。Person.prototype.proto===Object.prototye

构造函数的也都是对象,且由 Function 构造器生成,所以 Object 对象的 _proto_ 属性指向是 null。所以 null 是原型链的顶端

Object._proto_ ===Function.prototype;
Obejct.prototype._proto_ === null;

所以,所有的对象都是从 Obejct 对象继承的,Object 对象直接继承根对象 null。所有的构造函数都是继承自 Function 对象。

  • 所有对象都可以通过 _proto_ 访问,该属性指向对象的原型
  • 所有的函数对象都是有 prototype 属性,由构造函数创建的实例的 _proto_ 都会指向构造函数的prototype 的值
  • 所有的原型对象都有 constructor 属性,即为构造函数
  • 函数对象和原型对象通过 "prototype"和"constructor"属性进行相互关联