OneZero
OneZero

Reputation: 11904

Why is prototype assignment not working here?

var foo = {
    name: "foo"
};

var bar = {};

bar.prototype = foo;

document.writeln("Bar name: " + bar.name + "<br />");

And here's what I got in browser:

Bar name: undefined

Why is this happening? Shouldn't Javascript look up name on bar, and then go up on foo and finds it? Why is it simply undefined?

Upvotes: 1

Views: 127

Answers (4)

Oswald
Oswald

Reputation: 31647

The prototype property, that is used for inheritance in JavaScript, is a member of the constructor function. It is not a member of the object that is created from the constructor function.

The object that is created from the constructor function has an internal property [[Prototype]] which is the same as the prototype property of the constuctor function. When you access a property on an object and the object does not have that property on its own, the [[Prototype]] object is searched for that property. But the [[Prototype]] property itself is not accessible from the language (it's only there for specification purposes).

Upvotes: 0

georg
georg

Reputation: 214949

Unfortunately, in Javascript x.prototype != "prototype of x". x.prototype means "if x is a constructor (=function), x.prototype will be a prototype of new x". If x is not a function, x.prototype doesn't make sense.

This is no more and no less confusing than the rest of the language. Remember, Mr. Eich had only 10 days to create it [ref].

To assign a prototype to an already created object, ES6 (Harmony) offers setPrototypeOf. In other engines, there's a vendor-specific hack o.__proto__=.... Mostly, it's a bad idea.

Upvotes: 2

Alnitak
Alnitak

Reputation: 339786

You can't directly set the prototype property on a plain object.

When you define a (constructor) function you can specify the prototype property of that function, and when that constructor is subsequently invoked the given property will be attached to the prototype chain of the new object.

So this would work:

var foo = { name: "foo" };

function Bar() { ... }
Bar.prototype = foo;

var b = new Bar();
// b.name now exists

However in ES5 you should use Object.create instead.

Upvotes: 0

jAndy
jAndy

Reputation: 235982

As others already correctly explained, the prototype system doesn't work like that in ECMAscript. You should instead use ECMAscripts Object.create method, which will do the magic for you.

var foo = {
    name: "foo"
};

var bar = Object.create( foo );

console.log("Bar name: " + bar.name);

.create() will pretty much do this under the hood:

Object.create = (function(){
  function F(){}

  return function( o ){
      F.prototype = o;
      return new F()
  }
})();

Upvotes: 1

Related Questions