撸一遍原型链及其相关的知识点。

prototype和__proto__和constructor

  • prototype是只有函数才有的属性。
  • __proto__是每个对象都有的属性。

现在我们的起点就是一个创建好的对象,由他开始寻找他的原型链。

他的 __proto__ 指向谁

__proto__的指向取决于对象创建的方式。
下面这张图是三种常见方式创建对象后,__proto__指向谁。

`__proto__指向谁`
`__proto__指向谁`

他的 constructor 指向谁

所有对象都会从他的原型上继承一个 constructor 属性,并且这个 constructor 等于他的构造函数。

2019-3-21-JS的继承:原型链-2019-3-21-3
2019-3-21-JS的继承:原型链-2019-3-21-3

即:a.constructor === A.prototype.constructor == A
`

什么是原型链

对于有基于类的语言经验 (如 Java 或 C++) 的coder来说,JavaScript 有点令人困惑,因为它是动态的,并且本身不提供一个class实现。(在 ES2015/ES6 中引入了class关键字,但只是语法糖,JavaScript 仍然是基于原型的)。

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为__proto__)指向它的原型对象(prototype)。该原型对象也有一个自己的私有属性(__proto__) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

几乎所有 JavaScript 中的对象都是位于原型链顶端的Object的实例。

看一张图:

原型链
原型链

注意 指向Object.prototype的是 A.prototype.__proto__
而不是A.__proto__,而A.__proto__,下文解析。

Object和Function

你可能曾经发现过这么一个现象:

1
2
Function instanceof Object; //true
Object instanceof Function; //true

什么鬼?我们先说一下instanceof

instanceof究竟是运算什么的

对于 object instanceof constructor

简单的来说:instanceof运算符用于 测试 object的原型链中的 任何位置 是否存在constructor的prototype属性

注意:instanceof运算时会递归查找object的原型链,即object.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。

再说Object和Function

  1. Function

    1
    2
    3
    4
    console.log(Function.__proto__) // function() {}
    console.log(Function.prototype) // function() {}

    console.log(Function.__proto__===Function.prototype) //true

    Function__proto__就是他自己的prototype,并且是一个特殊的匿名函数。

  2. Object

    1
    2
    console.log(Object.__proto__) // function() {}
    console.log(Object.prototype) // Object的函数们,原型链的终点

    我们发现Object.__proto__也是一个匿名函数,那么他与Function__proto__是同一个吗?

  3. Function与Object

    1
    console.log(Object.__proto__===Function.__proto__) //true

    果然是同一个,那么这个特殊的匿名函数又在其中扮演什么角色呢?

    1
    2
    3
    4
    let her = Function.__proto__ // 那个匿名函数
    console.log(her.__proto__) //竟然是Object.prototype?
    console.log(her.prototype)
    //当然是undefined的了 Object.prototype没有prototype
  4. 关系图
    关系图

    终点还是 Object.prototype

  5. 结果
    根据上面的分析,我们知道了

    1
    2
    3
    4
    5
    // Object instanceof Function
    Object.__proto__ === Function.prototype

    // Function instanceof Object
    Function.__proto__.__proto__ === Object.prototype

    还有下面的运算也是应有之理了。

    1
    2
    Object.constructor === Function 
    Function.constructor === Function

一个并没有什么用的小结论

所有构造器的constructor都指向Function
Function的prototype指向一个特殊的匿名函数,而这个匿名函数的__proto__指向Object.prototype

所有的结论都会很快的遗忘,只有真正的理解其中的过程才是正理。
当然了,过程也是会忘的
所以要写下来呀 🐶

最后

本文部分图源 感谢博主

FLAG-1