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.