JS面向对象和原型链

Posted by hdj on October 12, 2019

前言

基准

    function Foo(){
      // do something
    }
    const f1 = new Foo() 
  1. Object 是所有对象的爸爸,所有对象都可以通过 proto 找到它
  2. Function 是所有函数的爸爸,所有函数都可以通过 proto 找到它
  3. Function.prototype 和 Object.prototype 是两个特殊的对象,他们由引擎来创建
  4. 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
  5. 函数的 prototype 是一个对象,也就是原型
  6. 对象的 proto 指向原型, proto 将对象和原型连接起来组成了原型

** 只有函数对象才有prototype属性,函数对象简单说就是由function声明的函数 **

一个实例【f1】拥有一个构造函数(constructor)和(proto),function 拥有(prototype,和__proto__)

实例的构造函数指向new 生成的函数【Foo】,__proto__指向 【Foo.prototype】

【Foo.prototype】的构造函数constructor是【Foo】,__proto__指向 【Function.prototype】

总结一

  1. constructor属性:指向构造函数 (对象类型有)

  2. prototype属性:原型对象,object类型(Function.prototype除外,后面会讲),不需要记它指向谁,因为它不指向谁,就是个对象(有点绕),总之记住它就是个对象就好,一个对象的原型对象的构造函数就是这个对象本身,下面有代码解释

  3. __proto__属性:指向构造函数的原型对象(函数,对象共有)

总结二(特殊情况)

Object.prototype.__proto__ === null

Function.constructor === Function

Function.__proto__ === Function.prototype

Function.prototype.__proto__ === Object.prototype

Function.prototype.__proto__.__proto__ === null

神图解释

js-原型图解

new 的原理

  1. 新生成了一个对象
  2. 链接到原型
  3. 绑定 this
  4. 返回新对象

    function create() {
     // 创建一个空的对象
     let obj = new Object()
     // 获得构造函数
     let Con = [].shift.call(arguments)
     // 链接到原型
     obj.__proto__ = Con.prototype
     // 绑定 this,执行构造函数
     let result = Con.apply(obj, arguments)
     // 确保 new 出来的是个对象
     return typeof result === 'object' ? result : obj
    }
    

instaceof 的原理

myInstaceonf(left,right){
  const r_p = right.prototype
  let left = left.__proto__
  while(1){
   if(left === null){
   return false
   }
   if(left === r_p){
   return true
   }
  left = left.__proto__
  }
  
}