原型、原型链、构造函数

146 阅读2分钟

3.1 原型、原型链、继承

Prototype 原型属性

只要创建一个函数,就会为这个函数创建一个 prototype 的属性

函数的 prototype属性 指向一个对象

  • 这个对象就是调用该构造函数而创建的实例的原型
  • 这个对象用途是包含可以 由特定类型的所有实例 共享的属性和方法

function Person() {

}
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
//person1 和 person2 的 原型

-proto- 属性

  • 这是每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。

  • 当调用构造函数创建一个新的实例之后,该实例内部将包含一个指针(-proto-)指向构造函数的原型对象

function Person() {

}
var person = new Person();

console.log(person.__proto__ === Person.prototype); // true

constructor 构造器属性

  • 创建了构造函数之后,其原型对象默认只会取得 constructor 属性;其他方法都是从 Object 继承来的

  • constructor 属性 是一个指向 prototype 属性所在函数指针

function Person() {

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

}
var person = new Person();
console.log(person.constructor === Person); // true

//当获取 person.constructor 时,其实 person 中并没有 constructor 属性
//当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性
person.constructor === Person.prototype.constructor

综合

function Person() {

}

var person1 = new Person();

console.log(person1.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
// 顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

原型链

原型的原型

原型也是一个对象,并且通过Object构造函数生成。结合之前所讲,实例的 proto 指向构造函数的 prototype ,所以我们再更新下关系图:

Object.prototype

Object.prototype 的原型为 null,所以顺着原型链查找属性/方法时 查到 Object.prototype 就可以停止查找了。

console.log(Object.prototype.__proto__ === null) // true

蓝色的线为原型链。

Function Object 鸡和蛋问题

起源

  • Function instanceof Object //true
  • Object instanceof Function //true

分析

  1. 原型链的顶端就是 Object.prototype, 所有对象均从Object.prototype继承属性

  2. //Function.prototype 直接继承 Object.prototype。
    Function.prototype.__proto__  === Object.prototype  //true
    
    //Object本身是个(构造)函数,是Function的实例,即`Object.__proto__`就是`Function.prototype`
    Object.__proto__ === Function.prototype  //true
    
    //Function.prototype 和 Function.__proto__ 为同一对象
    Function.prototype === Function.__proto__ //true
    Function.prototype.constructor === Function //true
    
    Function.prototype instanceof Object  //true
    Function.prototype instanceof Function  //false
    
  1. //Object Function Array等构造函数 继承自 Function.prototype
    Function instanceof Function  //true
    Object instanceof Function   //true
    Array|Number|Boolea|String instanceof Function   //true
    
    //Function.prototype 直接继承 Object.prototype
    Function instanceof Object  //true
    
  2. 得出继承的原型链

    Object.prototype <- Function.prototype <- Function|Objct|Array|Number|Boolea|String
    

参考:github.com/mqyqingfeng… juejin.cn/post/684490…