Object.getPrototypeOf与__proto__的区别

19
我知道后者是非标准的。但 Object.getPrototypeOf__proto__ 之间有什么区别吗?我正在研究javascript中原型链的工作方式,并希望在这部分得到清晰的说明。谢谢。
4个回答

22

来自 MDN:

Object.getPrototypeOf() 是旧版且已弃用的 object.__proto__ 属性的标准实现。然而,它是只读方法。

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


8

最初,__proto__ 是Mozilla浏览器早期版本(Firefox 3.5之前)中仅有的一种技巧。它在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

2
最后一段是错误的,因为你混淆了。一个对象的原型具有isPrototypeOf属性,而不是getPrototypeOfObject是一个函数,不是对象的原型。你代码的第一行应该写isPrototypeOf而不是getPrototypeOf,换句话说,你在最后一段的回答并没有回答这个问题,而是另一个问题。 - Pacerier

4

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*/

0

摘要:

在 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)))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接