为什么分配给__proto__不起作用

问题描述 投票:1回答:2

我正在照料这种行为的原因。

情况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__更改为null

'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()

情况3:-当我使用Object.setPrototypeOf()时效果很好

'use strict'
let animal = {
    eats: true,
    walk(){
        console.log('Animal Walk');
    }
}

let rabbit = {
    jumps: true,
    __proto__: null
}

Object.setPrototypeOf(rabbit, animal)
console.log(Object.getPrototypeOf(rabbit))
rabbit.walk()

所以为什么分配在第一种情况下不起作用?

javascript object prototype
2个回答
1
投票

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

  1. __proto__ token in object literals,可以指定对象的初始原型,和
  2. [__proto__(在创建对象后获取/设置)]

__proto__ accessor property不会更改__proto__原型的原因是rabbit.__proto__ = animalrabbit定义的访问器属性。由于创建的__proto__没有任何原型(通过在对象常量中使用Object.prototype),因此rabbit不会继承该访问器,因此__proto__: null只会在rabbit上创建一个名为rabbit.__proto__ = animal的属性,而不是更改它的原型。

rabbit的两个含义都是仅适用于Web的旧版(附件B)兼容性。使用__proto__(用于创建具有特定原型的对象),__proto__和(如果无法避免更改对象的原型)Object.create。浏览器外部的JavaScript引擎不需要实现Object.getPrototypeOf之类的附件B功能(尽管以我的经验,这些引擎不会在浏览器外部禁用其中的大多数功能)。


0
投票

我认为,原因Object.setPrototypeOf只能在构造函数属性中设置。你不能设置它。设定器将无法在__proto__之外使用。但是,__proto__是用于创建原型属性的扩展util函数。constructor在此处设置proto(override)(如果可用),否则它将使用原型创建新类。

来自setPrototypeOf

setPrototypeOf
© www.soinside.com 2019 - 2024. All rights reserved.