BonsaiDen / JavaScript-Garden

A collection of documentation about the most quirky parts of the JavaScript language.
http://bonsaiden.github.com/JavaScript-Garden
MIT License
3.45k stars 558 forks source link

primitives will simply get ignored when assigned as a prototype. is this right? #89

Closed idkiller closed 10 years ago

idkiller commented 13 years ago

in chapter "The prototype"

The Prototype Property

While the prototype property is used by the language to build the prototype chains, it is still possible to assign any given value to it. Although primitives will simply get ignored when assigned as a prototype.

is this really right?

when I test at firefox and chrome, assigned primitives really change prototype.

function foo() { this.x = 10; }

function bar() {}

bar.prototype = new foo();

bar.prototype = 1; // it was not ignored. prototype has changed really.
robotlolita commented 13 years ago

@idkiller Here you're changing a property, not the prototype chain. prototype is just a simple property, you can assign to it any value you want and it will just work. The magic of this property, however, comes when you use the new keyword to construct an object from a constructor function, which will make a fresh object with the prototype chain described by the constructor.

Now, here comes the catch: the actual prototype is a hidden property called [[Prototype]]. The specs don't require any implementation to expose it, and most don't do so. Some (like v8 and SpiderMonkey) expose this hidden property, usually as __proto__.

[[Prototype]] only accepts an Object or null, as you can see from the specs here: http://es5.github.com/#x8.6.2

And here is the proof:

>> var base = {a: 1}
>> var other = Object.create(base) // constructs a new object with [[Prototype]] === base
>> other.__proto__ === base
true
>> other.a
1
>> other.__proto__ = 'foo'
>> other.__proto__ === base
true
>> other.a
1
timruffles commented 11 years ago

Yes @killdream is quite correct - you can set an explicit prototype property, but to the interpreter this has nothing to do with the object's prototype. Simple huh? :)

However, the text is really not explicit enough around this. I will update it.

evverx commented 9 years ago
However, primitives will simply get ignored when assigned as a prototype.
function Foo() {}
Foo.prototype = 1; // no effect

Really?:)

function Foo() {}
(new Foo).constructor === Foo;
function Foo() {}
Foo.prototype = 1;
(new Foo).constructor === Object;

but who cares? :)

The default Foo.prototype object by default gets a public, non-enumerable property called .constructor, and this property is a reference back to the function (Foo in this case) that the object is associated with. See Creating Function Objects

Foo.prototype = 1 sets prototype property to non-object value. Quote from ES5 Construct:

If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
timruffles commented 9 years ago

PRs always welcome :)

On Sunday, 5 April 2015, Evgeny Vereshchagin notifications@github.com wrote:

However, primitives will simply get ignored when assigned as a prototype.

function Foo() {}Foo.prototype = 1; // no effect

Really?:)

function Foo() {} (new Foo).constructor === Foo;

function Foo() {}Foo.prototype = 1; (new Foo).constructor === Object;

but who cares? :)

The default Foo.prototype object by default gets a public, non-enumerable property called .constructor, and this property is a reference back to the function (Foo in this case) that the object is associated with. See Creating Function Objects http://es5.github.io/#x13.2

Foo.prototype = 1 sets prototype property to non-object value. Quote from ES5 Construct http://es5.github.io/#x13.2.2:

If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.

— Reply to this email directly or view it on GitHub https://github.com/BonsaiDen/JavaScript-Garden/issues/89#issuecomment-89756259 .

evverx commented 9 years ago

Yes, I know :) I'm reading and collecting inaccuracies now. Maybe I'll be back with PRs :)