简体   繁体   中英

Can't add method prototype to JavaScript object

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' ?

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

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;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM