JavaScript输入事件:保留for()循环变量

时间:2014-12-16 01:18:51

标签: javascript jquery variables events for-loop

我使用构造函数/原型方法开发了一个应用程序来构建和管理很少的对象。使用JavaScript和jQuery,其中一个原型创建输入字段,在onclick事件上声明了匿名函数。

在匿名函数中,我可以使用外部引用(var that = this)轻松访问主对象,并且我还能够访问链接到输入对象本身的属性。但是,我的输入字段是在for()循环中构建的,我还需要保留循环迭代的递归变量(我们用来看的着名“var i”)。

由于“i”值作为参考传递,因此每个输入将始终保留最后一个值“i”。所以我找到了一种解决方法,将输入对象归为自己的“i”属性。

所以我的问题是:这是一个好方法吗?或者我应该用另一种方式来完成这项工作?

以下是代码:

// Let's create the constructor
function familly(motherName,fatherName,children) {
    // We give to the properties their values
    this.motherName = motherName;
    this.fatherName = fatherName;
    this.children = children;
}

// Then we create a prototype that creates an input field for each child
familly.prototype.createChildrenInputs = function() {

    // I declare a variable that will serve as a reference to the main object (some people would name it "that")
    var famillyObject = this;

    // We pass into a loop all the children existing in the object property
    var children = this.children;
    for(var i in children) {

        // We create the input field
        var input = document.createElement('input');
            $(input).val(i);

            // !!! WORKAROUND !!! : I attach the "i" variable as a property to the input
            input.i = i;

            $(input).on('click', function() {

                // 1. The main object is accessible through the var famillyObject
                console.log(famillyObject);

                // 2. The value of the element is accessible with this.value
                console.log(this.value);


                // !!! HOWEVER !!!
                // ---------------

                // 3. The var "i" will always return "2"
                console.log(i);
                // 4. But the var "this.i" will show the good value (0, 1 or 2), since the reference was turned into a value with the workaround
                console.log(this.i);

            });
        document.body.appendChild(input);
    }
}

var mother = 'Nancy';
var father = 'Eric';
var children = [
    {
        'name':'Stephan',
        'gender':'male'
    },
    {
        'name':'Lois',
        'gender':'female'
    },
    {
        'name':'Andrew',
        'gender':'male'
    }
];

var newFamilly = new familly(mother,father,children);
newFamilly.createChildrenInputs();

1 个答案:

答案 0 :(得分:0)

这个主题在SO中有很好的涵盖,但我提供了答案,因为一些外围整理也是可能的......

而不是for()尝试使用this.children循环.forEach()。在每次迭代时,其函数参数将形成一个闭包捕获所有本地变量,包括i

familly.prototype.createChildrenButtons = function() {
    var famillyObject = this;
    this.children.forEach(function(child, i) {
        var $input = $('<input />').val(i).on('click', function() {
            console.log(famillyObject);
            console.log(this.value);
            console.log(i);
        });
        $(document).append($input);
    });
};