【问题标题】:How to keep variable in scope如何将变量保持在范围内
【发布时间】:2011-03-26 21:29:42
【问题描述】:

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

我用下面的循环来做这个

$(文档).ready(函数() { for (在 fieldCtrls 中的 ctrlName){ var ctrl = fieldCtrls[ctrlName]; ctrl.Initialize = 函数(){ //做一些事情 ctrl.someProperty = "newValue"; } ctrl.Validate=函数(){ //做更多的事情 ctrl.someProperty = "验证成功"; } }

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

fieldCtrls['id'].Validate();

【问题讨论】:

    标签: javascript scope closures


    【解决方案1】:

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

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

    【讨论】:

    • 啊,我为什么不厚此薄彼! ;)
    【解决方案2】:

    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 设置一个新范围,因此每个函数都会捕获不同的变量,而不是每次都捕获相同的变量。

    (注:未经测试,我不是 JavaScript 专家。然而,这个问题困扰着大多数支持闭包的脚本语言。)

    【讨论】:

    • 谢谢!你设法向我解释了关闭!我已经阅读了很多关于它的内容,但仍然没有掌握它。
    • 哇,我什至没有真正尝试过。我想我会发布这个,即使 Ivar 的解决方案在这种特殊情况下更好,但这更普遍适用。
    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2015-12-14
    • 2014-08-22
    • 1970-01-01
    • 2015-12-18
    • 2020-03-25
    • 2020-03-20
    • 1970-01-01
    相关资源
    最近更新 更多