Lac Viet
Lac Viet

Reputation: 720

prototype odd result when changing way to define

When trying to test prototype functionality, I got this odd result: Here is my first test:

<script>
function Hello() {
}
var a = new Hello();

Hello.prototype.name = "Fred";
alert(a.name);
</script>

And, here's the second one:

<script>
function Hello() {
}
var a = new Hello();

Hello.prototype = {
        name : "Fred",
}
alert(a.name);
</script>

I can't understand why the first will return a alert with "Fred" and the second is "undefined" though these mean the same thing? Could you help me with it? Thank you.

Upvotes: 1

Views: 46

Answers (3)

alex
alex

Reputation: 490163

When you define a function in JavaScript, the interpreter makes a special prototype property available on the function, which points to an object, in case you use that function as a constructor. The [[Prototype]] internal property points to this object when you create a new object using the constructor.

When you replace the prototype property with a new one, you are replacing that reference, and if you do it after you instantiate an object, you will find the prototype object appears to be stale (that object's [[Prototype]] is pointing to the original object that prototype pointed to).

Solutions

Only assign new properties directly on the prototype property.

var constructor = function() { };
constructor.prototype.someMethod = function() { };

Use an extend type function to extend the existing prototype property with your new object (in this example, I used Underscore's extend() function).

var constructor = function() { };
_.extend(constructor.prototype, { someMethod: function() { } });

Make sure after the constructor, assigning the prototype property is the very next step in your program (generally not recommended).

var constructor = function() { };
constructor.prototype = { someMethod: function() { } };

Upvotes: 2

karim79
karim79

Reputation: 342635

Your ordering is messed up. You need assign the object to the prototype before using the new operator:

function Hello() {
}

Hello.prototype = {
        name : "Fred",
}

var a = new Hello();
alert(a.name);​

Demo.

Upvotes: 1

jsalonen
jsalonen

Reputation: 30481

The two code snippets are not actually equal.

In the first script you only override Hello.prototype.name, while in the second script you override the whole content of Hello.prototype.

Upvotes: 0

Related Questions