JavaScript匿名函数参数传递

19

我有一些 JavaScript 代码(在一个对象中):

toggle: function() {
    var me = this;
    var handler = function() { me.progress() };
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

我对JavaScript还比较新,据我所知,上面的代码将me变量传递给了匿名函数。我想知道是否有更加声明式的方法来实现这个功能?我希望得到类似于以下代码的东西:

var handler = (function(o) { o.progress();})(this));

但是似乎这并没有起作用... 我有什么遗漏吗?这是一个“语言本身的工作方式,因此只需声明一个局部变量并处理它”的情况吗?

更新:

导致问题的源头是我对JavaScript中作用域和闭包的理解不清楚。我发现这篇文章帮助我更好地理解了一些。


1
它不起作用是因为你有一个多余的)。也许 var handler = (function(o) { o.progress();})(this); 可以工作? - pimvdb
5个回答

30
您可以使用".bind()"方法:
var handler = function() { this.progress(); }.bind(this);

新的浏览器有"bind()"方法,而Mozilla文档提供了一个稳定的实现,您可以使用它来修补旧版浏览器。


3
更加简洁的解决方案是 var handler = this.progress.bind(this)。感谢您的贡献! - Jose

6
原因
var handler = (function(o) { o.progress();})(this));

这段代码无法正常工作,因为它立即调用了匿名函数,因此立即调用了o.progress()并将匿名函数的返回值(未定义)分配给handler。您需要从外部函数返回一个实际的函数:

handler = (function(me){
    return function(){
        return me.progress();
    }
}(this));

相反地,这与变量赋值一样糟糕(但仍然有用,特别是如果需要在循环中执行此操作,使用变化的i而不是固定的this)。


顺便说一下,如果进度函数内没有对this的任何调用,则只需执行handler = this.progress(无需括号)即可。


5
匿名函数可以访问me,因为它是在外部函数(toggle函数)中声明的;它被外部函数所封闭。
您的handler函数将由setInterval调用,它不传递任何参数。这意味着您不能在处理程序函数本身中使用参数。
如果您真的想显式传递me,可以编写一个接受参数的函数,并使该函数返回一个无参数但可以访问创建者函数参数的匿名函数。
toggle: function() {
    var me = this;
    var handler = (function (o) { return function() { o.progress() }; })(me);
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

但这只是增加了一层重定向而没有真正使其更易读。除非将创建函数移到外面:

function createProgressHandler(o) {
    return function() {
        o.progress();
    };
}

// ...

toggle: function() {
    var me = this;
    var handler = createProgressHandler(me);
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

1
你那里有一个闭包。创建并分配给`handler`的函数保留对`me`对象的引用。这是正常的、日常的 JavaScript,这也通常是闭包的工作方式。

1
那不是他的问题。他抱怨this无法被封闭,迫使他使用var me = this - hugomg
我同意,但他想做的事情等于是在与语言作斗争。我和可能所有写JavaScript代码的人一样,都希望不用本地变量赋值,但它就是现状。 - Adam Crossland

0
你尝试过像这样返回函数吗?
var handler = function(o){
   return function(){
      o.progress();
   }
}(me);

现在你可以调用:

handler();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接