【问题标题】:Difference between Object.getPrototypeOf vs __proto__Object.getPrototypeOf 与 __proto__ 之间的区别
【发布时间】:2013-07-20 05:38:06
【问题描述】:

我知道后者是非标准的。但是Object.getPrototypeOf__proto__ 之间有区别吗?我正在研究 javascript 中的原型链是如何工作的,并希望在这部分清楚。

谢谢。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    来自MDN

    Object.getPrototypeOf() 是旧的和已弃用的 object.__proto__ 属性的标准实现。但是它是一个只读方法。

    因此,如果您正在读取值,它们基本上会完成相同的事情,除了 __proto__ 是非标准的。 __proto__ 也可能让您设置现有对象的原型,但通常这不是一个好主意,因此现在的标准是使用构造函数或Object.create 来创建具有特定原型的对象。也就是说,ES6 规范还定义了一个 setPrototypeOf 来设置对象的原型,尽管出于性能原因,除非明确需要,否则最好避免这样做。

    【讨论】:

      【解决方案2】:

      最初,__proto__ 是 Mozilla 浏览器早期版本(3.5 之前的 Firefox)中仅限 Mozilla 的黑客。它仅在 2008 年被编入 ECMAScript 3.1。

      一个区别是__proto__ 可以更改(虽然这是一种糟糕的设计实践),而getPrototypeOf 是一个读取函数。

      var parentObject = {"parentKey" : "parentValue"};
      var childObject = {"childKey" : "childValue"};
      childObject.__proto__ = parentObject;
      console.log(childObject.parentKey); // parentValue
      Object.getPrototypeOf(childObject) = {"parentKey" : "newValue"};
      // ReferenceError: Invalid left-hand side in assignment
      

      另一个区别是他们如何处理不太可能的名称冲突情况:

      var myObject = { __proto__ : "conflicts", getPrototypeOf : function () {return "does not conflict"} };
      console.log( myObject.getPrototypeOf() ); // "does not conflict"
      // all objects inherit from Object.prototype, not Object, so there is no conflict
      console.log( Object.getPrototypeOf(myObject) ) // Object {}
      console.log( myObject.__proto__ ); // Object {}, the value "conflicts" is lost
      

      【讨论】:

      • 最后一段是错误的,因为你很困惑。一个对象的原型有isPrototypeOf prop。 不是 getPrototypeOfObject 是一个函数,不是对象的原型。 ¶ 你的代码的第一行应该写isPrototypeOf 而不是getPrototypeOf,换句话说,你在最后一段中的答案不是回答这个问题而是另一个问题。
      【解决方案3】:

      Proxy 对待 ≪__proto__≫作为get:

      _ = new Proxy({}, {
        get:z=>console.log('a'),
        getPrototypeOf:z=>console.log('b'),
      });
      _.__proto__/*a*/
      

      ——和 ≪getPrototypeOf≫作为getPrototypeOf:

      _ = new Proxy({}, {
        get:z=>console.log('a'),
        getPrototypeOf:z=>console.log('b'),
      });
      Object.getPrototypeOf(_)/*b*/
      

      【讨论】:

        【解决方案4】:

        总结:

        在 javascript 中,对象的__proto__ 属性和Object.getPrototypeOf() 方法都是访问对象原型的方法。它们都使我们能够访问原型属性的引用

        那有什么区别呢?

        因为__proto__ 只是一个对象的属性,并且在当天被放在那里以访问对象的原型。 __proto__ 现在已弃用,某些 JS 引擎可能不再支持此属性。 Object.getPrototypeOf()Object.setPrototypeOf() 是现在应该用来检索原型的函数。

        示例:

        function Dog (name) {
          this.name = name;
        }
        
        Dog.prototype.bark = function () { console.log('woof'); };
        
        let dog = new Dog('fluffie');
        
        // DON'T:
        // Old method using __proto__ deprecated!
        console.log(dog.__proto__);
        
        // DO:
        // Using the newer getPrototypeOf function
        console.log(Object.getPrototypeOf(dog));
        
        // What about climbing up the prototype chain like this?
        console.log(dog.__proto__.__proto__);
        
        // We can simply nest the Object.getPrototypeOf() method calls like this:
        console.log(Object.getPrototypeOf(Object.getPrototypeOf(dog)))

        【讨论】:

          猜你喜欢
          • 2021-01-26
          • 1970-01-01
          • 1970-01-01
          • 2021-11-29
          • 2019-04-09
          • 2014-10-30
          • 2021-12-07
          • 2016-02-09
          • 2016-05-14
          相关资源
          最近更新 更多