如何将数据传递给JavaScript中的匿名函数?

0sc*_*car 5 javascript closures

当我将'this'传递给匿名函数时:

MyClass.prototype.trigger = function(){
    window.setTimeout(function(){this.onTimeout();},1000);
}
Run Code Online (Sandbox Code Playgroud)

我得到一个"this.onTimeout不是一个函数" - 错误.我想在匿名函数执行时'this'不再可用了吗?所以我一直这样做:

MyClass.prototype.trigger = function(){
    var me = this
    window.setTimeout(function(){me.onTimeout();},1000);
}
Run Code Online (Sandbox Code Playgroud)

这真的是你应该做的事情吗?它有点工作,但感觉很奇怪.

然后我们有这个例子:

$(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();

});
Run Code Online (Sandbox Code Playgroud)

这输出:

2
2
Run Code Online (Sandbox Code Playgroud)

不应该输出:

1
2
Run Code Online (Sandbox Code Playgroud)

代替?然后我发现将$ .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); });
}
Run Code Online (Sandbox Code Playgroud)

这输出:

1
2
Run Code Online (Sandbox Code Playgroud)

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

抱歉这个令人困惑和冗长的帖子.

Nea*_*all 5

你所经历的是正确的行为 - 这不是一个好的行为,但它是语言的一部分.在每个函数定义中重置"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. 作为构造函数(带"new")
    myNewObj = new MyConstructor(param1, param2);
    当您以这种方式调用函数时,"this"被初始化为一个新对象,该对象从函数的prototype属性继承方法和属性.在这种情况下,新对象将继承自MyConstructor.prototype.此外,如果您未明确返回值,则将返回"this".

您使用的解决方案是推荐的解决方案 - 将"this"的外部值分配给另一个在您的函数内仍然可见的变量.我唯一要改变的是将变量称为"那个",如TörökGábor所说 - 这是事实上的标准,并且可能使您的代码更容易为其他程序员阅读.