【发布时间】:2013-07-20 05:38:06
【问题描述】:
我知道后者是非标准的。但是Object.getPrototypeOf 和__proto__ 之间有区别吗?我正在研究 javascript 中的原型链是如何工作的,并希望在这部分清楚。
谢谢。
【问题讨论】:
标签: javascript
我知道后者是非标准的。但是Object.getPrototypeOf 和__proto__ 之间有区别吗?我正在研究 javascript 中的原型链是如何工作的,并希望在这部分清楚。
谢谢。
【问题讨论】:
标签: javascript
来自MDN:
Object.getPrototypeOf() 是旧的和已弃用的 object.__proto__ 属性的标准实现。但是它是一个只读方法。
因此,如果您正在读取值,它们基本上会完成相同的事情,除了 __proto__ 是非标准的。 __proto__ 也可能让您设置现有对象的原型,但通常这不是一个好主意,因此现在的标准是使用构造函数或Object.create 来创建具有特定原型的对象。也就是说,ES6 规范还定义了一个 setPrototypeOf 来设置对象的原型,尽管出于性能原因,除非明确需要,否则最好避免这样做。
【讨论】:
最初,__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。 不是 getPrototypeOf。 Object 是一个函数,不是对象的原型。 ¶ 你的代码的第一行应该写isPrototypeOf 而不是getPrototypeOf,换句话说,你在最后一段中的答案不是回答这个问题而是另一个问题。
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*/
【讨论】:
在 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)))
【讨论】: