代码之家  ›  专栏  ›  技术社区  ›  0scar

如何在javascript中将数据传递给匿名函数?

  •  5
  • 0scar  · 技术社区  · 16 年前

    当我将“this”传递给这样的匿名函数时:

    MyClass.prototype.trigger = function(){
        window.setTimeout(function(){this.onTimeout();},1000);
    }
    

    我得到一个“this.ontimeout不是函数”-错误。我想匿名函数执行时“this”不再可用?所以我一直在这样做:

    MyClass.prototype.trigger = function(){
        var me = this
        window.setTimeout(function(){me.onTimeout();},1000);
    }
    

    你真的应该这样做吗?有点管用,但感觉很奇怪。

    然后我们有一个例子:

    $(function(){
        function MyClass(){
            this.queue = new Array();
        }
        MyClass.prototype.gotAnswer = function(count){
            $('body').append("count:"+count+"<br/>");
        }
        MyClass.prototype.loadAll = function(){
            var count = 0;
            var item;
            while(item = this.queue.pop()){
                count++;
                var me = this;
                $.getJSON("answer.html",{},function(data){me.gotAnswer(count);});
            }
        }
    
        var o = new MyClass();
        o.queue.push(1);
        o.queue.push(2);
        o.loadAll();
    
    });
    

    此输出:

    2
    2
    

    它不应该输出:

    1
    2
    

    相反?然后我发现将$.getjson语句放在另一个函数中可以使它全部工作:

    MyClass.prototype.loadAll = function(){
        var count = 0;
        var item;
        while(item = this.queue.pop()){
            count++;
            this.newRequest(count);
        }
    }
    MyClass.prototype.newRequest = function(count){
        var me = this;
        $.getJSON("answer.html",null,function(data){ me.gotAnswer(count); });
    }
    

    此输出:

    一
    二
    

    (或者相反)这里发生了什么?将变量传递给一个异常函数的正确方法是什么?

    抱歉,这篇冗长而混乱的文章。

    3 回复  |  直到 11 年前
        1
  •  5
  •   Neall    16 年前

    你所经历的是正确的行为-这不是一个好的行为,但它是语言的一部分。“this”的值在内部重置 每一个 函数定义。有四种方法可以调用具有不同设置方式的函数“this”。

    1. 常规函数调用
      myFunc(param1, param2);
      这种调用函数的方式总是将“this”重置为全局对象。你的案子就是这样的。
    2. 将其作为方法调用
      myObj.myFunc(param1, param2);
      这毫不奇怪地将“this”设置为正在调用方法的任何对象。这里,“this”=“myobj”。
    3. 应用方法调用
      myFunc.apply(myObj, [param1, param2])
      这是一个有趣的方法-这里“this”被设置为作为apply方法的第一个参数传递给的对象-这就像在没有该方法的对象上调用一个方法(请注意,函数是以这种方式编写来调用的)。默认情况下,所有函数都有apply方法。
    4. 作为一名建造师(用“新的”)。
      myNewObj = new MyConstructor(param1, param2);
      以这种方式调用函数时,“this”被初始化为从函数的原型属性继承方法和属性的新对象。在这种情况下,新对象将从myConstructor.prototype继承。此外,如果不显式返回值,则将返回“this”。

    您使用的解决方案是推荐的解决方案-将“this”的外部值赋给另一个在函数内部仍然可见的变量。我唯一要改变的是调用变量“that”,正如T_ r_ k g_bor所说——这是事实上的一种标准,可能会让其他程序员更容易阅读您的代码。

        2
  •  3
  •   Community CDub    8 年前

    您对闭包感到困惑。

    对于第一个问题,是的,你是对的,这是可以做到的。唯一的区别是有一个命名变量的约定 that 持有 this .

    MyClass.prototype.trigger = function(){
        var that = this;
        window.setTimeout(function(){that.onTimeout();},1000);
    }
    

    StackOverflow上已经有了一个很好的关于这个的线程。检查问题答案 How does a javascript closure work? .

    第二个问题是 Javascript closure inside loops - simple practical example .

        3
  •  0
  •   ElLocoCocoLoco    11 年前

    如果在新方法中使用newRequest,则会遇到同样的问题:必须使用“for”或“while”语句。 另一个解决方案可能是创建一个闭包:

    像这样:

    $.getJSON("answer.html",{},(function(me){return function(data){me.gotAnswer(count);}})(this));