0

我想为基于 Json 文件的对象编写 getter 和 setter 函数。我复制了 John Resig 的书(Appress Pro JavaScript 技术)的以下代码,但它不起作用,并且这些函数没有添加到对象中。你能告诉我为什么以及正确的代码是什么?

// 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());
4

2 回答 2

3

你已经使用了一个函数来创建一个闭包,但是你忘记了传递i给它。您还需要对函数this内部的不同引用,因为其中的上下文更改为.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
}
于 2013-08-12T09:57:51.507 回答
2

在您的 IIFE 中,this实际上是window. 您必须使用以下方式指定上下文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);
    }
}

或者用另一个变量保持对它的引用:

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

如果您处于严格模式,您的代码将抛出错误而不是误导性地成功:

TypeError: Cannot set property 'getname' of undefined
于 2013-08-12T09:59:11.687 回答