简体   繁体   中英

Why these JavaScript functions don't add to this object?

I want to write a getter and setter functions for an object based on a Json files. I copied the below code of John Resig's book(Appress Pro JavaScript Techniques) but it doesn't work and these functions don't add to the object.Can you tell me why and what is the right code?

// Create a new user object that accepts an object of properties
function User(properties) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
  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: 44
});

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

// However, we're able to access its value using the new getname()
// method, that was dynamically generated
alert(user.getname());

You've used a function to create a closure, but you've forgotten to pass i into it. You'll also need a different reference to this inside the function , as the context changes in it to window .

function User(properties) {
    var i, me = this;
    for (i in properties) (function (i) {
        // Create a new getter for the property
        me["get" + i] = function () { // using `me` because `this !== me`
            return properties[i];
        };

        // Create a new setter for the property
        me["set" + i] = function (val) {
            properties[i] = val;
        };
    }(i)); // i passed into function closure
}

In your IIFE, this is actually window . You have to specify the context by using Function.prototype.call :

function User(properties) {
    // Iterate through the properties of the object, and make sure
    // that it's properly scoped (as discussed previously)
    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);
    }
}

Or keep a reference to it with another variable:

function User(properties) {
    var that = this;

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

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

If you were in strict mode, your code would throw an error instead of misleadingly succeeding:

TypeError: Cannot set property 'getname' of undefined

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