javascript回调函数,变量映射

javascript callback functions, variable mapping

我总是在javascript中使用回调函数,但我从未理解回调如何知道它可以采用哪些变量。

我们来看下面的示例代码;

1
2
3
4
5
var friends = ["Mike","Stacy","Andy","Rick"];

friends.forEach(function (name, index){
    console.log(index + 1 +"." + name);
});

这在逻辑上输出;

1
2
3
4
1. Mike
2. Stacy
3. Andy
4. Rick

事实上,以下所有内容都会输出相同的内容;

1
2
3
4
5
6
7
8
9
10
11
friends.forEach(function (index, name){
    console.log(name + 1 +"." + index);
});

friends.forEach(function (foo, bar){
    console.log(bar + 1 +"." + foo);
});

friends.forEach(function (x, y){
    console.log(y + 1 +"." + x);
});

forEach中的回调函数如何知道如何解释nameindex? 换一种说法; 回调如何知道数组有值和索引? 很明显,你给回调函数的输入变量的名称并不重要,但顺序是,所以如何映射事物?

从这里开始,我还想将这些知识应用到其他对象中,而不仅仅是列表。 那么变量如何从对象映射到回调函数? 这是事先在对象中定义的东西吗?


在本机支持Array.prototype.forEach的浏览器中,它可能以不同的方式实现,但一般情况下,您将使用Function.prototype.call以正确的顺序(无论可能是什么)执行提供参数的callback函数,同时迭代您的集合。

forEach的MDN条目具有以下代码,用于在不支持它的浏览器中为数组实现它:

1
2
3
4
5
6
7
8
9
10
11
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (fn, scope) {
        'use strict';
        var i, len;
        for (i = 0, len = this.length; i < len; ++i) {
            if (i in this) {
                fn.call(scope, this[i], i, this);
            }
        }
    };
}

In other words; how does the callback know that the array has values and indexes? It is clear that the name you give to the input variables of the callback function aren't important but the order is, so how are things mapped?

详细说来,回调函数只是一个函数,可以任意命名(abindexvalue一样);在它执行之前它对阵列一无所知。您正在调用forEach的数组知道它具有索引,并且这些索引具有值,并且它还期望回调函数以特定顺序接受参数。事物并没有完全映射到数组和回调函数之间,forEach函数只是依次将每个索引及其对应的值传递给回调函数。


该函数需要三个参数。它们的名称并不重要。它会将正确的值传递给函数。

forEach executes the provided callback once for each element of the array with an assigned value. It is not invoked for indexes which have been deleted or which have been initialized to undefined.

callback is invoked with three arguments:

  • the element value
  • the element index
  • the array being traversed

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach


为了更容易理解该特定方法,让我们看一下Array.prototype.forEach兼容性代码:

1
2
3
4
5
6
7
8
9
10
11
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (fn, scope) {
        'use strict';
        var i, len;
        for (i = 0, len = this.length; i < len; ++i) {
            if (i in this) {
                fn.call(scope, this[i], i, this);
            }
        }
    };
}

仔细看看fn.call:这一行调用传递的回调函数,传递上下文(scope)和参数(this[i] - 当前元素,i - 索引,this - 整个数组)。

有关如何调用与someFunction(arguments)不同的函数的更多信息,请查看以下链接:

1.Function.prototype.bind

2.Function.prototype.call

3.Function.prototype.apply