原型链

27 阅读2分钟

原型链

  • 原型对象 prototype; 隐式对象/原型proto; 可以理解为实例化后的变量才有原型,而其创建类是有原型对象属性
  • Object 具有原型对象和隐式对象.并且其隐式对象是指向 Function.prototype
  • Function 具有原型对象和隐式对象,其原型对象和隐式对象是全等的 Function.prototype === Function.proto
  • 使用 function 创建的构造函数,其原型对象指向此类,隐式对象指向 Function
  • ps:
    1. 只有实例化对象才有proto属性.
    2. JS 中的函数可以作为函数使用,也可以作为类使用
    3. Object.proto === Function.prototype ===Function.protot;Function.prototype.proto === Object.prototype;
    4. 作为类使用的函数实例化时需要使用 new
    5. 为了让函数具有类的功能,函数都具有 prototype 属性。
    6. 为了让实例化出来的对象能够访问到 prototype 上的属性和方法,实例对象的proto指向了类的 prototype。所以 prototype 是函数的属性,不是对象 的。对象拥有的是proto,是用来查找 prototype 的。
    7. prototype.constructor 指向的是构造函数,也就是类函数本身。改变这个指针并不能改变构造函数。
    8. 对象本身并没有 constructor 属性,你访问到的是原型链上的 prototype.constructor。
    9. 函数本身也是对象,也具有proto,他指向的是 JS 内置对象 Function 的原型 Function.prototype。所以你才能调用 func.call,func.apply 这些方 法,你调用的其实是 Function.prototype.call 和 Function.prototype.apply。
    10. prototype 本身也是对象,所以他也有proto,指向了他父级的 prototype.proto和 prototype 的这种链式指向构成了 JS 的原型链。原型链的最 终指向是 Object 的原型。Object 上面原型链是 null,即 Object.prototype.proto === null。
    11. 另外评论区有朋友提到:Function.proto === Function.prototype。这是因为 JS 中所有函数的原型都是 Function.prototype,也就是说所有函数都是 Function 的实例。Function 本身也是可以作为函数使用的----Function(),所以他也是 Function 的一个实例。类似的还有 Object,Array 等,他们也可以作为函数使用:Object(), Array()。所以他们本身的原型也是 Function.prototype,即 Object.proto === Function.prototype。换句话说,这些可 以 new 的内置对象其实都是一个类,就像我们的 Puppy 类一样。
    12. ES6 的 class 其实是函数类的一种语法糖,书写起来更清晰,但原理是一样的。