【问题标题】:When creating javascript objects is the "Object" object just created once and just referenced by everything's __proto__?创建 javascript 对象时,“对象”对象是否只创建一次并被所有内容的 __proto__ 引用?
【发布时间】:2019-06-25 23:41:31
【问题描述】:

当创建 javascript 对象时,“Object”对象只是创建了一次,并且只是被所有东西的 proto 引用

【问题讨论】:

  • 是和不是。其他对象引用 Object.prototype(通过它们的[[Prototype]] 链),而不是 Object。
  • 是的,多个对象可以继承同一个对象。

标签: javascript object prototype


【解决方案1】:

1) 对象的__proto__ 属性表示创建时将哪个对象用作原型。

2) 因为__proto__ 指向一个对象,所以它是一个引用,因为这始终是对象在 JavaScript 中通过引用存储的方式。

3) 使用Object.create() 创建的新对象将具有等于函数参数的__proto__。因此,并非所有对象都具有相同的__proto__

4) Object 是一个built-in 函数,仅定义一次。

5) 对象字面量的 __proto__Object.prototype(不是 Object):

const obj = {};
console.log(obj.__proto__ === Object.prototype); // true

那是因为创建一个对象字面量和做是一样的:

Object.create(Object.prototype)

【讨论】:

    【解决方案2】:

    是的,首要的“对象”对象被创建一次,它的原型被不同的 JavaScript(JS) 对象引用,例如数组或其他创建的对象。但是,如果您创建的对象继承自您创建的另一个超类对象,则其__proto__ 将首先在其原型链中引用超类的对象原型。

    当你创建一个对象并调用一个方法时,JS 通过原型链寻找方法。如果 JS 没有在对象中找到该方法,它会尝试从对象的超类中委托该方法。如果它仍然没有找到该方法,它将再上一层委托,并最终委托给“对象”对象。假设您创建了一个 Person 对象作为 Hero 对象的超类:

    let Person = function(name) {
        this.name = name;
    }
    
    Person.prototype.greet = function() {
        console.log("Hello, my name is " + this.name + ".")
    }
    
    let Hero = function(name) {
        Person.call(this, name);
    }
    
    Hero.prototype = Object.create(Person.prototype);
    Hero.prototype.constructor = Hero;
    
    Hero.prototype.fight = function(villain) {
        console.log("Hero, " + this.name + ", defeated " + villain + "!");
    }
    

    Hero.prototype = Object.create(Person.prototype); 行中,您允许JS 将Person.prototype 委托给Hero.prototype。这里,Hero.prototype.__proto__ 指向Person.prototype。如果在Hero.prototypePerson.prototype 中都没有找到该方法,那么它最终将委托给位于其原型链[[Prototype]] 中的Object.prototype(@RobG 感谢您澄清这一点)。

    【讨论】:

    • 注意use of __proto__ is deprecated,所以请不要使用它。请改用Object.getPrototypeOf。全局 Object 只有一个 prototype 属性。 ;-)
    • 是的,这正是我的想法,因为创建一个新对象完全违背了整个概念,但它在所有原型教程中都轻而易举。
    • Re "因此,所有 JS 原生对象都会引用 "Object" 对象的原型,但不会引用用户创建的对象。"。所有使用普通 ECMAScript 方法“由用户”创建的对象都是原生对象,并且它们的 [[Prototype]] 链上都有 Object.prototype。
    • @RobG 我知道__proto__ 的使用已被弃用。那么Object.create(Hero.prototype)的使用最终还是使用__proto__?这是一个不好的做法? (@RobG,@girvain)。另外,@RobG 感谢您指出我的错误。我将编辑我的帖子。
    • @mikekoo 不,Object.create 根本不使用__proto__ getter/setter,它直接访问底层内部的 [[prototype]] 属性,就像Object.getPrototypeOf,@987654342 @ 和 Object.prototype.__proto__ 做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多