如何将数据传递给JavaScript中的匿名函数? [英] How is data passed to anonymous functions in JavaScript?

查看:133
本文介绍了如何将数据传递给JavaScript中的匿名函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我把'this'传递给一个匿名函数,如下:

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



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

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

这真的是你应该做的事吗?



然后我们有这个例子:

 <$> c $ c> $(function(){
function MyClass(){
this.queue = new Array();
}
MyClass.prototype.gotAnswer = function ){
$('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


b $ b

?然后我发现把$ .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){meGotAnswer(count);});
}



此输出:

  1 
2



<这里发生了什么?将变量传递给一个匿名函数的正确方法是什么?



对于混乱和冗长的帖子,很抱歉。

解决方案

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


  1. 常规函数调用

     myFunc(param1,param2); 

    这种调用函数的方式将总是将this重置为全局对象。


  2. 调用它作为一个方法

     myObj.myFunc(param1,param2); 

    这不奇怪的设置this 到该方法被调用的任何对象。

    p> myFunc.apply(myObj,[param1,param2])应用方法调用

    在这里,this==myObj这是一个有趣的 - 这里this设置为您传递的对象作为apply方法的第一个参数 - 它就像在没有该方法的对象上调用一个方法(小心函数被写为称为这种方式)。所有函数默认都有apply方法。

  3. 作为一个构造函数(带有new)

     myNewObj = new MyConstructor(param1,param2); 

    以这种方式调用函数时,this被初始化为一个新对象,该对象从函数的prototype属性继承方法和属性。在这种情况下,新对象将从MyConstructor.prototype继承。此外,如果您不明确返回值,将返回this。


解决方案 - 将this的外部值赋给另一个在函数中仍然可见的变量。我唯一需要改变的是调用变量that作为TörökGábor说 - 这是事实上的标准,可能会使你的代码更容易阅读为其他程序员。


When I pass 'this' to an anonymous function like so:

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

I get a "this.onTimeout is not a function"-error. I guess that 'this' is no longer available at the time the anonymous function is executing? So I've been doing this:

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

Is this really how you're supposed to do things? It kinda works, but it feels weird.

Then we have this example:

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

});

This outputs:

2
2

Shouldn't it output:

1
2

instead? Then I discovered that putting the $.getJSON-statement in another function makes it all work:

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); });
}

This outputs:

1
2

(Or the other way around.) What's happening here? What is the right way to pass variables to an anonnymous function?

Sorry for the confusing and lengthy post.

解决方案

What you are experiencing is the correct behavior - it's not a good behavior, but it's part of the language. The value of "this" is reset inside every function definition. There are four ways to call a function that have different ways of setting "this".

  1. The regular function invocation

    myFunc(param1, param2);

    This way of calling a function will always reset "this" to the global object. That's what's happening in your case.

  2. Calling it as a method

    myObj.myFunc(param1, param2);

    This unsurprisingly sets "this" to whatever object the method is being called on. Here, "this" == "myObj".

  3. Apply method invocation

    myFunc.apply(myObj, [param1, param2])

    This is an interesting one - here "this" is set to the object you pass as the first parameter to the apply method - it's like calling a method on an object that does not have that method (be careful that the function is written to be called this way). All functions by default have the apply method.

  4. As a constructor (with "new")

    myNewObj = new MyConstructor(param1, param2);

    When you call a function this way, "this" is initialized to a new object that inherits methods and properties from your function's prototype property. In this case, the new object would inherit from MyConstructor.prototype. In addition, if you don't return a value explicitly, "this" will be returned.

The solution you used is the recommended solution - assign the outside value of "this" to another variable that will still be visible inside your function. The only thing I would change is to call the variable "that" as Török Gábor says - that's sort of the de-facto standard and might make your code easier to read for other programmers.

这篇关于如何将数据传递给JavaScript中的匿名函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆