最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Create getter and setter in Javascript - Stack Overflow

programmeradmin4浏览0评论

I am following a tutorial to create getter and setter in Javascript, I have the code like this:

// Create a new User object that accept an object of properties
function User(properties) {
    // Iterate through the properties of the object, and make
    // sure it's properly scoped
    for (var i in properties) { (function(){
        // Create a new getter for the property
        this['get' + i] = function() {
            return properties[i];
        };

        // Create a new setter for the property
        this['set' + i] = function(val) {
            properties[i] = val;
        };
    })(); }
}

// Create a new User object instance and pass in an object of
// properties to seed it with
var user = new User({
    name: 'Bob',
    age: 28
});

// Just note that the name property does not exist, as it's private
// within the property object
console.log(user.name == null);

// However, we are able to access its value using the new getname()
// method, that was dynamically generated
console.log(user.getname());

However, console shows error saying user does not have method getname. The code is trying to dynamically generate getter and setter method, it looks ok to me. Any thoughts?

I am following a tutorial to create getter and setter in Javascript, I have the code like this:

// Create a new User object that accept an object of properties
function User(properties) {
    // Iterate through the properties of the object, and make
    // sure it's properly scoped
    for (var i in properties) { (function(){
        // Create a new getter for the property
        this['get' + i] = function() {
            return properties[i];
        };

        // Create a new setter for the property
        this['set' + i] = function(val) {
            properties[i] = val;
        };
    })(); }
}

// Create a new User object instance and pass in an object of
// properties to seed it with
var user = new User({
    name: 'Bob',
    age: 28
});

// Just note that the name property does not exist, as it's private
// within the property object
console.log(user.name == null);

// However, we are able to access its value using the new getname()
// method, that was dynamically generated
console.log(user.getname());

However, console shows error saying user does not have method getname. The code is trying to dynamically generate getter and setter method, it looks ok to me. Any thoughts?

Share Improve this question asked Jul 20, 2013 at 17:30 RexRex 2512 gold badges4 silver badges10 bronze badges 10
  • Your in-loop function is losing the this, do a var t = this; outside loop and refer to t inside. – Paul S. Commented Jul 20, 2013 at 17:33
  • 2 You could also use es5 getters/setters. – beatgammit Commented Jul 20, 2013 at 17:34
  • Then you need to know that i as you use it in the getter/setter will always have the same value (i.e., the last value of the loop) for all getters/setters the code creates. – sjngm Commented Jul 20, 2013 at 17:35
  • 1 Why do you have an anonymous function in your for loop? What purpose does it serve? Are you populating from a web service? – beatgammit Commented Jul 20, 2013 at 17:36
  • @tjameson It's there for a reason. If it wasn't there than i would always be the last value. However he is using it wrong as your suppose to pass i as an argument to the function. – Shawn31313 Commented Jul 20, 2013 at 17:40
 |  Show 5 more ments

3 Answers 3

Reset to default 15

The other answers are correct in that you need to pass i into your anonymous function, but you could also do this with ES5 Getters and Setters:

// Create a new User object that accept an object of properties
function User(properties) {
    var self = this; // make sure we can access this inside our anon function
    for (var i in properties) {
        (function(i) {
            Object.defineProperty(self, i, {
                // Create a new getter for the property
                get: function () {
                    return properties[i];
                },
                // Create a new setter for the property
                set: function (val) {
                    properties[i] = val;
                }
            })
        })(i);
    }
}

The benefit of using ES5 getters and setters is that now you can do this:

var user = new User({name: 'Bob'});
user.name; // Bob
user.name = 'Dan';
user.name; // Dan

Since they're functions, they modify the passed in properties, not just the object itself. You don't have to use getN or setN anymore, you can just use .N, which makes using it look more like accessing properties on an object.

This approach, however, isn't universally portable (requires IE 9+).

Here's what I'd probably do in practice though:

function User(properties) {
    Object.keys(properties).forEach(function (prop) {
        Object.defineProperty(this, prop, {
            // Create a new getter for the property
            get: function () {
                return properties[prop];
            },
            // Create a new setter for the property
            set: function (val) {
                properties[prop] = val;
            }
        })
    }, this);
}

The above gets rid of your for loop. You're already using an anonymous function, so might as well get the most of it.

Probably a closure issue:

function User(properties) {
    // Iterate through the properties of the object, and make
    // sure it's properly scoped
    for (var i in properties) { 
        (function(i){
            // Create a new getter for the property
            this['get' + i] = function() {
                return properties[i];
            };

            // Create a new setter for the property
            this['set' + i] = function(val) {
                properties[i] = val;
            };
        }.call(this, i));
    }
}

Also, as @Paul pointed out, this was actually referring to the function which was contained in the for loop. Not the User function. I fixed that by using a call and assigning the User this to the function (no need for extra variable).

Your in-loop function is losing the this, do a var t = this; outside loop and refer to t inside. Also, pass i into your function.

function User(properties) {
    var t = this, i;
    for (i in properties) (function (i) {
        t['get' + i] = function () { return properties[i]; };
        t['set' + i] = function (val) { properties[i] = val; };
    }(i));
}
发布评论

评论列表(0)

  1. 暂无评论