Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
[].forEach.call()在JavaScript中做什么?_Javascript_Arrays_Foreach_Ecmascript 5_Nodelist - Fatal编程技术网

[].forEach.call()在JavaScript中做什么?

[].forEach.call()在JavaScript中做什么?,javascript,arrays,foreach,ecmascript-5,nodelist,Javascript,Arrays,Foreach,Ecmascript 5,Nodelist,我查看了一些代码片段,发现多个元素在节点列表上调用函数,并将forEach应用于空数组 例如,我有一些类似于: [].forEach.call( document.querySelectorAll('a'), function(el) { // whatever with the current node }); 但我不明白它是怎么工作的。有人能给我解释一下forEach前面的空数组的行为以及调用如何工作吗?空数组的原型中有一个属性forEach,它是一个函数对象。(空数组只是获取所有a

我查看了一些代码片段,发现多个元素在节点列表上调用函数,并将forEach应用于空数组

例如,我有一些类似于:

[].forEach.call( document.querySelectorAll('a'), function(el) {
   // whatever with the current node
});

但我不明白它是怎么工作的。有人能给我解释一下forEach前面的空数组的行为以及
调用如何工作吗?

空数组的原型中有一个属性
forEach
,它是一个函数对象。(空数组只是获取所有
array
对象都具有的
forEach
函数引用的一种简单方法。)函数对象反过来又具有一个
call
属性,该属性也是一个函数。调用函数的
调用
函数时,它使用给定参数运行函数。第一个参数在被调用函数中变为
this


您可以找到
调用
函数的文档。
forEach
的文档是。

空数组的原型中有一个属性
forEach
,它是一个函数对象。(空数组只是获取所有
array
对象都具有的
forEach
函数引用的一种简单方法。)函数对象反过来又具有一个
call
属性,该属性也是一个函数。调用函数的
调用
函数时,它使用给定参数运行函数。第一个参数在被调用函数中变为
this

您可以找到
调用
函数的文档。
forEach
的文档是。

返回一个
节点列表
,它类似于一个数组,但不完全是一个数组。因此,它没有
forEach
方法(数组对象通过
array.prototype
继承)

由于
NodeList
类似于数组,数组方法实际上会对其起作用,因此通过使用
[].forEach.call
可以在
NodeList
的上下文中调用
array.prototype.forEach
方法,就好像您能够简单地执行
您的NodeList.forEach(/*…*/)

请注意,空数组文字只是扩展版本的快捷方式,您可能也会经常看到:

Array.prototype.forEach.call(/*...*/);
返回一个
节点列表
,它类似于一个数组,但不完全是一个数组。因此,它没有
forEach
方法(数组对象通过
array.prototype
继承)

由于
NodeList
类似于数组,数组方法实际上会对其起作用,因此通过使用
[].forEach.call
可以在
NodeList
的上下文中调用
array.prototype.forEach
方法,就好像您能够简单地执行
您的NodeList.forEach(/*…*/)

请注意,空数组文字只是扩展版本的快捷方式,您可能也会经常看到:

Array.prototype.forEach.call(/*...*/);

它可以更好地使用

Array.prototype.forEach.call( document.querySelectorAll('a'), function(el) {

});
is所做的是
document.querySelectorAll('a')
返回一个类似于数组的对象,但它不从
数组
类型继承。
因此,我们从
数组.prototype
对象调用
forEach
方法,上下文作为
文档返回的值。querySelectorAll('a')
使用

Array.prototype.forEach.call( document.querySelectorAll('a'), function(el) {

});
is所做的是
document.querySelectorAll('a')
返回一个类似于数组的对象,但它不从
数组
类型继承。
因此,我们从
数组调用
forEach
方法。prototype
对象的上下文是
文档返回的值。querySelectorAll('a')
[]
是一个数组。
这个数组根本不用

它被放在页面上,因为使用数组可以访问数组原型,比如
.forEach

这比键入
Array.prototype.forEach.call(…)要快得多

接下来,
forEach
是一个将函数作为输入的函数

[1,2,3].forEach(function (num) { console.log(num); });
…对于
this
中的每个元素(其中
this
类似于数组,因为它具有
长度
,您可以访问它的部分,如
this[1]
),它将传递三个信息:

  • 数组中的元素
  • 元素的索引(第三个元素将通过
    2
  • 对数组的引用
  • 最后,
    .call
    是函数拥有的原型(它是在其他函数上被调用的函数)。
    .call
    将取其第一个参数,并用您传递的
    call
    替换常规函数中的
    ,作为第一个参数(
    未定义的
    将在日常JS中使用
    窗口
    ,或是您传递的任何内容,如果处于“严格模式”)。其余参数将传递给原始函数

    [1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
        console.log(i + ": " + item);
    });
    // 0: "a"
    // 1: "b"
    // 2: "c"
    
    因此,您正在创建一种调用
    forEach
    函数的快速方法,并且您正在将
    从空数组更改为所有
    标记的列表,并且对于每个
    按顺序调用提供的函数

    编辑 逻辑结论/清理 下面是一篇文章的链接,建议我们放弃函数式编程的尝试,每次都坚持手动、内联循环,因为这种解决方案既有黑客味又难看

    我要说的是,虽然
    .forEach
    不如它的对应物,
    .map(transformer)
    .filter(predicate)
    .reduce(combiner,initialValue)
    ,但当您真正想做的只是修改外部世界(而不是数组)n次,同时可以访问
    arr[I]
    i

    那么,我们如何处理这种差异呢?因为格言显然是一个才华横溢、学识渊博的人,我想说一句
    function countArgs (...allArgs) {
      return allArgs.length;
    }
    
    function logArgs (...allArgs) {
      return allArgs.forEach(arg => console.log(arg));
    }
    
    function extend (subject, ...others) { /* return ... */ }
    
    
    var nodeArray = [ ...nodeList1, ...nodeList2 ];
    
    function forEach( list, callback ) {
        Array.prototype.forEach.call( list, callback );
    }
    
    forEach( document.querySelectorAll('a'), function( el ) {
       // whatever with the current node
    });
    
    NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
    
    document.querySelectorAll('a').forEach(function(el) {
      // whatever with the current node
    });
    
    if (window.NodeList && !NodeList.prototype.forEach) {
        NodeList.prototype.forEach = function (callback, thisArg) {
            thisArg = thisArg || window;
            for (var i = 0; i < this.length; i++) {
                callback.call(thisArg, this[i], i, this);
            }
        };
    }
    
    const forEach = (array, callback) => {
      if (!array || !array.length || !callback) return
      for (var i = 0; i < array.length; i++) {
        callback(array[i], i);
      }
    }
    
    forEach(document.querySelectorAll('.a-class'), (item, index) => {
      console.log(`Item: ${item}, index: ${index}`);
    });
    
    [].forEach.call(document.querySelectorAll('a'), a => {})
    
    Array.from(document.querySelectorAll('a')).forEach(a => {})
    
    [].forEach.call( document.querySelectorAll('a'), function(el) {
       // whatever with the current node
    });
    
    var arr = document.querySelectorAll('a');
    arr.forEach(function(el) {
       // whatever with the current node
    });