JavaScript

我眼中的JS原型链

2018-05-15  本文已影响0人  CodorMonkey

原型链的知识,涉及到构造函数(constructor)、实例(instance)、原型对象(prototype),下面将一一讲解(最后还附带instanceof原理~)

什么是构造函数?

在JS中,任意函数都能当做构造函数,实际编码中,一般都有约定俗成的规范,例如:函数名首字母大写;函数名使用名词,而不是动词;一般只会用 new 的方式使用,不会直接调用;and so on...(编不下去了....)。

什么是实例?

一般指通过使用 new 构造函数(),返回的对象。

什么是原型对象?

原型对象没啥概念可讲,先看下面一段代码:

演示代码

构造函数.prototype,这个就是原型对象...

下面再上一张图

构造函数、实例、原型对象关系图

最后再来说说原型链,每个对象都有一个特殊的属性protoproto指向这个对象的构造函数的原型对象,以演示代码为例,Person是构造函数,p是实例对象,p.proto === Person.prototype为true(演示代码第7行),由于prototype即原型对象也是一个对象,它也有proto属性,这样就形成了一个链条,也就是原型链,原型链的顶端为Object.prototype。

原型链有什么用?

模拟继承,OOP的关键,暂时就讲这么多,以后再细讲。

instanceof原理
原理示意图

检测实例对象的原型对象与构造函数的原型是否是同一个对象,如果不是,根据实例对象的原型链依次查找,直到相等,或者到达原型链顶端。

上面文字可能表达的不是很清楚,下面上代码:

function myInstanceOf (obj, constructor) {
  // 对象的原型对象
  let objProto = Object.getPrototypeOf(obj);
  // 构造函数的原型对象
  let constructorProto = constructor.prototype;

  if (objProto === constructorProto) {
    return true;
  } else {
    while (objProto = Object.getPrototypeOf(objProto)) {
      if (objProto === constructorProto) {
        return true;
      }
    }
    return false;
  }
}

function Person (name) {
  this.name = name;
}

Person.prototype.hi = function () {
  console.log(`Hi, My name is ${this.name}`);
};

let p = new Person('Monkey');
p.hi();
console.log('------------------------------------------------');
let other = {name: 'Lucy'};

console.log(`p is myInstanceOf Person : ${myInstanceOf(p, Person)}`);
console.log(`p is myInstanceOf Object : ${myInstanceOf(p, Object)}`);
console.log(`other is myInstanceOf Person : ${myInstanceOf(other, Person)}`);
console.log(`other is myInstanceOf Object : ${myInstanceOf(other, Object)}`);
console.log('------------------------------------------------');
console.log(`p is instanceof Person : ${myInstanceOf(p, Person)}`);
console.log(`p is instanceof Object : ${myInstanceOf(p, Object)}`);
console.log(`other is instanceof Person : ${myInstanceOf(other, Person)}`);
console.log(`other is instanceof Object : ${myInstanceOf(other, Object)}`);</pre>

使用myInstanceOf和instanceof的结果是一致的

上一篇 下一篇

猜你喜欢

热点阅读