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

JavaScript输入事件:保留for()循环变量,javascript,jquery,variables,events,for-loop,Javascript,Jquery,Variables,Events,For Loop,我使用构造器/原型方法开发了一个应用程序来构建和管理一些对象。使用JavaScript和jQuery,其中一个原型创建输入字段,在onclick事件中声明匿名函数 在匿名函数内部,我可以通过外部引用(var that=this)轻松访问主对象,并且还可以访问链接到输入对象本身的属性。但是,我的输入字段是在for()循环中构建的,并且我还需要保留循环迭代的reccursive变量(我们经常看到的著名的“var I”) 由于“i”值作为引用传递,因此每个输入将始终保留“i”得到的最后一个值。因此,我

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

在匿名函数内部,我可以通过外部引用(var that=this)轻松访问主对象,并且还可以访问链接到输入对象本身的属性。但是,我的输入字段是在for()循环中构建的,并且我还需要保留循环迭代的reccursive变量(我们经常看到的著名的“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();

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

不要使用
for()
尝试使用
.forEach()
循环遍历
this.children
。在每次迭代中,它的函数参数将形成一个闭包,捕获所有局部变量,包括
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);
    });
};
familly.prototype.createChildrenButtons=function(){
var FamilyObject=此;
this.children.forEach(函数(child,i){
var$input=$('').val(i).on('click',function()){
控制台日志(FamilyObject);
console.log(this.value);
控制台日志(i);
});
$(文档)。追加($input);
});
};

使用bind(),一个函数包装,[].map而不是for等…我认为Alexis是对的,他放的链接看起来像是我的答案。然而,我仍然想知道我的变通方法是否是一个好的解决方案。谢谢dandavis,这些一行的答案对我并没有真正的帮助,因为你需要在不删除“this.value”输入参数的情况下,对如何在特定情况下使用bind()进行一些上下文分析。我认为最好不要发明你自己的解决方案来解决JS中关于for循环的最常见问题。它不坏,但也不伟大;如果html向元素添加了一个“i”属性,它就会崩溃。即使有了更好的属性名,我觉得对于循环值的闭包或避免闭包,也有广泛理解的范例,不使用闭包会降低可读性。但它是有效的!您可以将“for(var i in children)”替换为“[].map.call(this.children,function(child,i){”,而不必担心在您下面的内容会发生变化(它会给您一个“private i”)感谢Roamer,这似乎很有效。我毫不怀疑这个主题已经被很好地涵盖了,问题是我无法找到一些与那些流行关键词相关的东西:for循环、变量、范围等。因为我对JavaScript是新手,所以也很难知道所有这些精确的术语和概念来定位正确的东西。无论如何,感谢你的帮助我们的解释!@dandavis,从问题中我了解到
this.children
是数组而不是集合。如果是,那么它有一个
.forEach()
方法。不需要
.apply()
。如果
this.children
是集合,那么
this.children.each(…)
这是一条路。@Pierre Luc同意,因此很难理解。祝你好运。是的,我看错了代码,从来没有按过小提琴,对不起。不需要把它弄得更复杂。别担心@dandavis,我最初看到“孩子”这个词,也有同样的想法。