Reputation: 712
I was messing around with Javascript prototypes, and I don't understand why this works:
function User(un) {
this.username = un;
}
User.prototype.method_name = function() {
return this.username;
};
var user = new User("Michael");
console.log(user.method_name());
But this doesn't:
function User(un) {
this.username = un;
return{
getUsername: function (){
return username;
},
setUsername: function(username) {
username = un;
}
};
}
User.prototype.method_name = function() {
return this.username;
};
var user = new User("Michael");
console.log(user.method_name());
Why does adding the "return" statement throw Object #<Object> has no method 'method_name'
?
Upvotes: 1
Views: 954
Reputation: 7930
Returning an object circumvents the usual return value of a constructor, which is the this
variable. Instead of returning this
, you're returning some other object, and that object doesn't have a username property or a method_name method. This is roughly what happens at each point in the code:
function User(un) {
this.username = un; // puts username on the 'this' object
// returns an entirely different, unrelated object that doesn't use User's prototype
return{
getUsername: function (){
return un;
},
setUsername: function(username) {
un = username;
}
};
}
// sets method_name on the prototype of the 'this' object for User
User.prototype.method_name = function() {
return this.username;
};
var user = new User("Michael"); // passes a new User.prototype as the implicit 'this' in the User function
console.log(user.method_name());
Instead, try this:
function User(un) {
this.username = un;
this.getUsername = function (){
return un;
};
this.setUsername = function(username) {
un = username;
};
}
User.prototype.method_name = function() {
return this.username;
};
Upvotes: 3
Reputation: 147363
Because in the second example, the object you return isn't a new "User" instance, but a plain Object instance.
When you use the new key word with a constructor, the object returned by default inherits from the constructor's prototype, so you have an inheritance chain like:
user -> User.prototype -> Object.prototype -> null
If you return some other object, it doesn't inherit from the constructor and you have an inheritance chain like:
user -> Object.prototype -> null
Upvotes: 4