【问题标题】:How Object constructor comes in the prototype object of any function?Object 构造函数是如何出现在任何函数的原型对象中的?
【发布时间】:2020-12-05 10:21:59
【问题描述】:

在下面的代码中

function Hello(){
      //
 }

console.dir(Hello);

我的问题是:

Object从哪里以及如何进入Hello的原型对象?

将Object带到那里的幕后发生了什么?

【问题讨论】:

    标签: javascript prototype prototype-programming


    【解决方案1】:

    不要将prototype 作为函数的属性与其实际原型混淆(可通过__proto__/getPrototypeOf() 访问并用于名称解析机制等)。

    在您的示例中,Hello.prototype 用作使用构造函数模式创建的所有对象的共享原型:也就是说,当使用 new 运算符调用此函数时。是的,这个原型本质上是一个对象:

    function Hello() {}
    console.log(Hello.prototype); // {}
    console.log(Object.getPrototypeOf(Hello)); // function () { [native code] }
    
    const newHello = new Hello();
    console.log(Object.getPrototypeOf(newHello) === Hello.prototype); // true
    
    const anotherHello = new Hello();
    console.log(Object.getPrototypeOf(anotherHello) === Hello.prototype); // true
    console.log(Object.getPrototypeOf(newHello) === Object.getPrototypeOf(anotherHello)); 
    // apparently true as well

    这就是 JS 中基于原型的对象模型的关键思想:实例之间共享的所有东西都只存储一次。

    请注意,箭头函数没有prototype 属性(因为您不希望将它们用作构造函数):

    const FatArrowHello = () => {};
    console.log(FatArrowHello.prototype); // undefined
    const newFatArrowHello = new FatArrowHello();
    // VM424: 1 Uncaught TypeError: FatArrowHello is not a constructor
    // at < anonymous >: 1: 18

    【讨论】:

      【解决方案2】:

      Hello 的原型对象中 Object 是从哪里来的,又是怎么来的?

      它没有,但控制台显示确实使它看起来像那样。 Hello.prototype上的对象原型其实是Object.prototype,而不是Object

      function Hello() {
      }
      console.dir(Hello);
      console.log(Hello.prototype.__proto__ === Object); // false
      console.log(Hello.prototype.__proto__ === Object.prototype); // true

      控制台将Object 显示为Hello.prototype.__proto__类型(粗略地说),而不是其值。

      (注意:我在上面使用了__proto__,因为这就是控制台在您的示例中向您显示它的方式,但我强烈建议不要使用__proto__ 访问器代码。请改用Object.getPrototypeOf。)


      我想你知道这一点,但为了完整性:Hello.prototype 的原型是 Object.prototype 的原因是传统函数(和 class 构造函数)的 prototype 属性是由 JavaScript 引擎创建的当它创建函数时。对于传统的函数和基类,原型对象的创建就像使用对象字面量:{}。所以那个对象有Object.prototype 作为它的原型。 (使用extends 的类的工作方式略有不同。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        相关资源
        最近更新 更多