【问题标题】:Javascript inheritance : How prototype chain works between native prototypesJavascript 继承:原型链如何在原生原型之间工作
【发布时间】:2019-10-19 13:32:56
【问题描述】:

我们知道 Javascript 中的所有内容都继承自 Object:

所以如果我使用如下构造函数创建一个对象:

function Rabbit() {
  this.color = 'White'
}

let obj = new Rabbit();

alert(Rabbit.__proto__ === Function.prototype)       //true
alert(obj.__proto__ === Rabbit.prototype)            //true       
alert(obj.__proto__.__proto__ === Object.prototype)  //true

alert(Function.__proto__ === Object.prototype)  //false
alert(Object.getPrototypeOf(Function) === Object.getPrototypeOf(Object))  //true

前 3 个结果是有意义的,因为 obj 继承自 Rabbit 函数,该函数本身继承自 Function。但是如果Function 继承自Object 那么为什么第四个结果是False。还有为什么Object 和Function 有相同的原型(最后的结果)?

谁能解释一下这种行为。我在这里错过了什么吗?

【问题讨论】:

  • 图表中的所有(大部分)对象都(间接)从Object.prototype继承,而不是从Object继承。
  • Object 和 Function 就像您图中的 function f(args) { … }。

标签: javascript function object inheritance prototype


【解决方案1】:
alert(Object.getPrototypeOf(Function) === Object.getPrototypeOf(Object)) // true

Function 和Object 都是函数,它们的原型是Function.prototype。可以验证

Object.getPrototypeOf(Function) === Function.prototype // true
Object.getPrototypeOf(Object) === Function.prototype // true

这个对象被用来创建Function函数的原型,因此

Function.__proto__ === Function.prototype // true

而不是

Function.__proto__ === Object.prototype // false

alert(Object.getPrototypeOf(Function) === Function.prototype)
alert(Object.getPrototypeOf(Object) === Function.prototype)
alert(Function.__proto__ === Function.prototype)

【讨论】:

    【解决方案2】:

    这样的问题最好用图片来解释(就像你问题中的那个):

    Legend:
    
       blue color = objects
       {} = simple object (+constructor name)
       Ⓟ = prototype object (+constructor name)
    
       magenta color = functions (ƒ + function name)
    

    基本上,__proto__ 函数链是:

    concrete function (e.g. Rabbit, Object or Function itself) 
    -> abstract function (aka Function.prototype) 
    -> Object.prototype 
    -> null 
    

    【讨论】:

    • 哇,谢谢。一张照片中有很多有价值的信息。你能多评论一下这些部分吗?例如,f Object 与 P Object 是什么,对于 Rabbit {} Rabbit、f Rabbit 和 P Rabbit 也是如此。另外,这里的f 是什么?
    • f 和洋红色是函数,蓝色是对象,(P) 是原型对象,{} 是简单对象。 null 为空;)
    • @VSX:ƒ后面的部分是函数名。只是ƒ 是一个没有名字的函数(匿名)。您的表达式对应于从ƒ Object __proto__ 和ƒ Function __proto__ 到匿名函数的两个箭头
    • 此类问题的最终资源是标准:ecma-international.org/ecma-262/8.0。它不是特别用户友好,但确实包含所有答案。
    • 不想听起来很挑剔,但我发现那个网站真的很混乱。甚至无法搜索特定的关键字(左上角的搜索没有任何作用)。
    【解决方案3】:

    您将函数构造函数的原型 Function.__proto__(等效于 Object.getPrototypeOf(Function))与函数原型 Function.prototype.__proto__ 混淆了。

    function Rabbit() {
      this.color = 'White'
    }
    
    let obj = new Rabbit();
    
    console.log(Rabbit.__proto__ === Function.prototype)       //true
    console.log(obj.__proto__ === Rabbit.prototype)            //true       
    console.log(obj.__proto__.__proto__ === Object.prototype)  //true
    
    console.log(Function.prototype.__proto__ === Object.prototype)  //true
    console.log(Object.getPrototypeOf(Function.prototype) === Object.getPrototypeOf(Object.prototype))  //false

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多