为什么分配给__proto__对象不起作用?

时间:2020-04-04 09:37:15

标签: javascript object prototype

情况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()

为什么作业在第一种情况下不起作用?

2 个答案:

答案 0 :(得分:5)

好的,这有点棘手。 :-)您的代码使用两种不同的__proto__含义:

  1. 可以__proto__ token in object literals指定对象的初始原型,并且
  2. __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();
         }
     }
}