情况1:-最初,在对象常量中,我将__proto__
分配为null,然后尝试将其重新分配给animal
,这是行不通的。
'use strict'
let animal = {
eats: true,
walk(){
console.log('Animal Walk');
}
}
let rabbit = {
jumps: true,
__proto__: null
}
rabbit.__proto__ = animal
console.log(Object.getPrototypeOf(rabbit))
rabbit.walk()
情况2:-现在,我在对象常量中将__proto__
分配为animal
,后来我尝试将其重新分配给null
,它将__proto__
更改为{{1} }。
null
情况3:-当我使用'use strict'
let animal = {
eats: true,
walk(){
console.log('Animal Walk');
}
}
let rabbit = {
jumps: true,
__proto__: animal
}
rabbit.__proto__ = null
console.log(Object.getPrototypeOf(rabbit))
rabbit.walk()
时效果很好
Object.setPrototypeOf()
为什么作业在第一种情况下不起作用?
答案 0 :(得分:5)
好的,这有点棘手。 :-)您的代码使用两种不同的__proto__
含义:
__proto__
token in object literals指定对象的初始原型,并且__proto__
accessor property(在创建对象后获取/设置) rabbit.__proto__ = animal
不会更改rabbit
原型的原因是__proto__
是Object.prototype
定义的访问器属性。由于您创建的rabbit
没有任何原型(通过在对象常量中使用__proto__: null
),rabbit
不会继承该访问器,因此rabbit.__proto__ = animal
只是在{{ 1}}称为rabbit
,而不是更改其原型。
__proto__
的两个含义都是仅兼容旧网络(附件B)的东西。使用__proto__
(用于创建具有特定原型的对象),Object.create
和(如果无法避免更改对象的原型)Object.getPrototypeOf
。浏览器外部的JavaScript引擎不需要实现Object.setPrototypeOf
之类的附件B功能(尽管以我的经验,引擎不会在浏览器外部禁用其中的大多数功能)。
答案 1 :(得分:-1)
我认为,原因__proto__
仅可以在构造函数属性中设置。你不能设置它。设置器将无法在constructor
之外使用。但是,setPrototypeOf
是扩展的util函数,用于创建原型属性。
在这里setPrototypeOf
设置proto(override)(如果可用),否则它将使用原型创建新类。
来自developer.mozilla.org
if (!Object.setPrototypeOf) {
// Only works in Chrome and FireFox, does not work in IE:
Object.prototype.setPrototypeOf = function(obj, proto) {
if(obj.__proto__) {
obj.__proto__ = proto;
return obj;
} else {
// If you want to return prototype of Object.create(null):
var Fn = function() {
for (var key in obj) {
Object.defineProperty(this, key, {
value: obj[key],
});
}
};
Fn.prototype = proto;
return new Fn();
}
}
}