JS函数返回另一个函数

时间:2010-04-28 13:38:46

标签: javascript function arguments

我想了解已经用于返回函数的变量。 这是示例代码

Prototype = {}

Prototype.F =
{
  bind: function()
  {
    var args = arguments, __method = args.shift(), object = args.shift();
    return function()
    {
        return __method.apply(object, args.concat(arguments));
    }
  }
}

function ObjectA()
{
    ...
    this.addListener = Prototype.F.bind(this.eventSource.addListener,
        this.eventSource);
    ...
}


var a = ObjectA();
a.addListener(this); // assuming 'this' here will point to some window object

据我所知,bind()中的返回函数在最后一行调用之前不会被计算。可以接受。因此 addListener 将包含一个包含'apply'的函数体。

但是我不明白,当调用 addListener 时,它会有什么样的参数?特别是 _method args 将始终未初始化?

3 个答案:

答案 0 :(得分:1)

bind返回的函数对bind函数的参数是closure,因此__method参数将是bind的第一个参数(在您的示例调用中,这将是this.eventSource.addListener函数)。

闭包基本上是具有本质绑定到它们的数据的函数。这是一个更简单的例子:

function makeAlert(msg) {
    return function() {
        alert(msg);
    }
}
var myalert = makeAlert("Hi there!");
myalert(); // Alerts "Hi there!"

makeAlert返回的函数“关闭”(保留访问权限)创建它的makeAlert函数调用范围内的事物,包括msg参数。这就是为什么当我们稍后调用该函数时,即使对msg的调用早已完成,它仍然具有makeAlertMore about closures here.

关于闭包的一个关键事项是,他们可以保留对定义范围的所有的访问权限,而不仅仅是他们明显使用的东西。例如:

function init() {
    var data;

    data = /* ...build some really big array of data...*/;

    document.getElementById('foo').onclick = function() {
        this.style.display = "none";
    };
}

即使事件处理程序与大数据数组无关,它也会保留对它的引用,因此在调用init之后将数据保留在内存中。这是因为它所拥有的链接是一个幕后对象(松散地称为“变量对象”),它是所有参数的容器,也是定义它的范围内的局部变量。 (在这种特殊情况下,如果您不需要所有这些数据,只需在结尾处将data设置为undefined。事件处理程序仍然会引用data,但是引用不再保存数组,因此可以回收数组的内存。)

答案 1 :(得分:0)

_method和args将始终初始化,因为您在第一次调用

时定义它们
this.addListener = Prototype.F.bind(this.eventSource.addListener, this.eventSource);

在那里,你会得到那个_method this.eventSource.addListener,而args就是那两个论点。

答案 2 :(得分:0)

在函数范围内,arguments是一个类似数组的对象,它包含调用函数时提供的值,无论函数定义是否定义了参数。

所以这个电话:

Prototype.F.bind(this.eventSource.addListener, this.eventSource);

导致了这个:

var args = arguments, __method = args.shift(), object = args.shift();

arguments包含2个项目:无论this.eventSource.addListenerthis.eventSource指向何时调用该函数。将2个项目的集合复制到args,然后将项目从集合移至__methodobject

因为调用bind实际上生成了另一个函数,所以新函数中的arguments实例将是不同的 - 它将具有在该调用时提供的参数。调用arguments的原始bind保存在args中,并与后来的函数调用中的arguments结合使用。