如何在范围内保持变量

时间:2010-08-08 07:23:02

标签: javascript scope closures

我有一个关联的对象数组,我想用许多函数进行扩展。 myCtrls //Array of objects

我使用以下循环

执行此操作
$(document).ready(function() {
    for (ctrlName in fieldCtrls){
        var ctrl = fieldCtrls[ctrlName];

        ctrl.Initialize = function(){
            //Do some stuff
            ctrl.someProperty = "newValue";
        }
        ctrl.Validate= function(){
            //Do some more stuff
            ctrl.someProperty = "validation ok";
        }
}

稍后,我执行这样的函数。但是变量'ctrl'现在总是指向'fieldCtrls'中的最后一个对象。如何使变量'ctrl'在'initialize()'和'Validate()'中工作?

fieldCtrls['id'].Validate();

2 个答案:

答案 0 :(得分:3)

范围将更改为调用对象 - fieldCtrls['id']。因此,您应该能够使用this访问内部属性。

ctrl.Validate= function(){
  //Do some more stuff
  this.someProperty = "validation ok";
}

答案 1 :(得分:1)

This blog post描述了您所看到的问题。 var ctrl声明实际上被解释为函数本地,而不是循环本地。

你可以通过写下这样的东西来解决这个问题:

$(document).ready(function() {
    for (ctrlName in fieldCtrls){
        function(ctrl) { // create a new anonymous function ...
            ctrl.Initialize = function(){
                //Do some stuff
                ctrl.someProperty = "newValue";
            }
            ctrl.Validate= function(){
                //Do some more stuff
                ctrl.someProperty = "validation ok";
            }
        }(fieldCtrls[ctrlName]); // ... and call the function right away
    }
}

这为每个循环迭代强制ctrl的新范围,因此每个函数捕获一个不同的变量,而不是每次都相同的变量。

(N.B。未经测试,我不是JavaScript大师。但是,这个问题困扰了大多数支持闭包的脚本语言。)