我使用构造函数/原型方法开发了一个应用程序来构建和管理很少的对象。使用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();
答案 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);
});
};