Case 1 :- Initially in object literal I assign __proto__
to null and then I'm trying to reassign it to animal
, which is not working.
'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()
Case 2:- Now i assign __proto__
in object literal as animal
and later i try to reassign it to null
, it changes __proto__
to null
in this case.
'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()
Case 3:- When i use Object.setPrototypeOf()
it works fine
'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()
Why isn't the assignment working in the first case?
Okay, this is a bit tricky. :-) There are two different __proto__
meanings being used by your code:
__proto__
token in object literals that can specify the object's initial prototype, and__proto__
accessor property (when you get/set it after object creation)The reason rabbit.__proto__ = animal
doesn't change rabbit
's prototype is that __proto__
is an accessor property defined by Object.prototype
. Since you create rabbit
without any prototype (by using __proto__: null
in the object literal), rabbit
doesn't inherit that accessor, so rabbit.__proto__ = animal
just creates a property on rabbit
called __proto__
rather than changing its prototype.
Both of those meanings for __proto__
are legacy web-only (Annex B) compatibility things. Use Object.create
(to create an object with a specific prototype), Object.getPrototypeOf
, and (if you can't avoid changing an object's prototype) Object.setPrototypeOf
. JavaScript engines outside of browsers aren't required to implement Annex B features like __proto__
(though in my experience, engines don't disable most of them outside browsers).