1

let p={};
p.__proto__=Array.prototype;
console.log(p.slice);   //ƒ slice() { [native code] }

However.. What's the difference?

let o=Object.create(null);
o.__proto__=Array.prototype;
console.log(o.slice); //undefined.
Liam
  • 27,717
  • 28
  • 128
  • 190
qqwenwenti
  • 63
  • 5
  • This [Link](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes) might help you. – kunal panchal Apr 12 '21 at 08:04
  • Does this answer your question? [Creating JS object with Object.create(null)?](https://stackoverflow.com/questions/15518328/creating-js-object-with-object-createnull) – Liam Apr 12 '21 at 08:08
  • [*They are not equivalent. `{}.constructor.prototype == Object.prototype` while `Object.create(null)` doesn't inherit from anything and thus has no properties at all.*](https://stackoverflow.com/a/15518712/542251) – Liam Apr 12 '21 at 08:10
  • I know `Object.create(null)` got no prop. or prototype. But then I assigned `Array.prototype` to it. Should it inherit from Array? – qqwenwenti Apr 12 '21 at 08:12
  • Read the linked answer ***no properties at all***, not even `__proto__` look at the [screen shots in this](https://stackoverflow.com/a/15518712/542251) – Liam Apr 12 '21 at 08:22
  • 1
    *But then I assigned Array.prototype to it. Should it inherit from Array* no it doesn't work like that. Your object has no intial link to object, all you've done is assign a property that happens to be called `__proto__` to the prototype of Array. This is not the same thing as updating the prototype of a prototype based object – Liam Apr 12 '21 at 08:24
  • Thank you Liam. I know now `o` doesn't even have [[prototype]] so it got no chain at all. Any object needs that chain (__proto__) to follow through something anyway. But here NO this chain. – qqwenwenti Apr 12 '21 at 08:30

1 Answers1

3

__proto__ is not an ordinary property, it's an accessor, that is, some function ("setter") gets called when you assign anything to it and is responsible for setting the internal hidden [[Prototype]] property. This function is located in Object.prototype, so if your object is not connected to Object.prototype, the function is not invoked. As a result, obj.__proto__ = xxx simply creates a new property named __proto__ in your object, which doesn't do anything.

In pseudocode:

Object.prototype = {
   get __proto__() {
       return this.[[Prototype]]
   }
   set __proto__(xxx) {
       this.[[Prototype]] = xxx
   }
}

myObject = {} // extends Object.prototype
myObject.__proto__ = xxx  // setter called!
myObject.[[Prototype]] is now xxx

myObject = Object.create(null) // extends null
myObject.__proto__ = xxx // no setter called 
myObject.[[Prototype]] is still null
georg
  • 211,518
  • 52
  • 313
  • 390
  • _your object is not connected to Object.prototype_ cuz it doesn't have the accessor `__proto__` to call setter. Thx~ – qqwenwenti Apr 12 '21 at 08:39