什么是[] .forEach.call()在JavaScript中吗? [英] What does [].forEach.call() do in JavaScript?

查看:107
本文介绍了什么是[] .forEach.call()在JavaScript中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是看着code的一些片段,我发现多个元素调用了与应用于空数组一个foreach节点列表的功能。

I was looking at some snippets of code, and I found multiple elements calling a function over a node list with a forEach applied to an empty array.

例如我有这样的:

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

但我不明白它是如何工作的。任何人都可以解释我的空数组的行为在foreach的正面和呼叫是如何工作的?

推荐答案

[] 是一个数组。结果
此阵列根本不使用。

[] is an array.
This array isn't used at all.

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

It's being put on the page, because using an array gives you access to array prototypes, like .forEach.

这仅仅是比打字快 Array.prototype.forEach.call(...);

接下来,的forEach 是一个函数,它接受一个函数作为输入...

Next, forEach is a function which takes a function as an input...

[1,2,3].forEach(function (num) { console.log(num); });

...并为每个元素这个(其中这个是类似数组的,因为它有一个长度键,您可以访问它的部件,如将此[1] ),它会通过三件事情:

...and for each element in this (where this is array-like, in that it has a length and you can access its parts like this[1]) it will pass three things:


  1. 数组中的元素

  2. 元素的索引(第三个元素会通过 2

  3. 要对数组的引用

最后, .CALL 是一个原型,功能有(这是一个都会调用其他函数的函数)。结果
.CALL 将其第一个参数,替换这个常规函数内不管你通过了呼叫,作为第一个参数(未定义将使用窗口在日常的JS,或将成为任何你过去了,如果严格模式)。的参数的其余部分将被传递到原来的功能。

Lastly, .call is a prototype which functions have (it's a function which gets called on other functions).
.call will take its first argument and replace this inside of the regular function with whatever you passed call, as the first argument (undefined or null will use window in everyday JS, or will be whatever you passed, if in "strict-mode"). The rest of the arguments will be passed to the original function.

[1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
    console.log(i + ": " + item);
});
// 0: "a"
// 1: "b"
// 2: "c"

因此​​,你要创建一个快速的方法来调用的forEach 功能,你改变这个从空数组到所有的列表< A> 标签,并为每个< A> IN-顺序,你调用的函数提供的。

Therefore, you're creating a quick way to call the forEach function, and you're changing this from the empty array to a list of all <a> tags, and for each <a> in-order, you are calling the function provided.

下面,有一篇文章建议我们放弃在函数式编程尝试,并坚持手工,行内循环,每一次​​,因为该解决方案是黑客十岁上下,丑陋的链接。

Below, there's a link to an article suggesting that we scrap attempts at functional programming, and stick to manual, inline looping, every time, because this solution is hack-ish and unsightly.

我说,虽然 .forEach 比它的同行少帮助, .MAP(变压器) .filter(predicate)。降低(组合,初值),它仍然是目的时,所有你真正想要做的是改变外界(不是数组),n次,同时有机会获得为改编[I] I

I'd say that while .forEach is less helpful than its counterparts, .map(transformer), .filter(predicate), .reduce(combiner, initialValue), it still serves purposes when all you really want to do is modify the outside world (not the array), n-times, while having access to either arr[i] or i.

那么,我们如何应对的差距,作为座右铭显然是一个有才华和有知识的人,我想想象,我知道我在做什么/我要去哪里(现在,然后...。 ..other时候,它的头先学习)?

So how do we deal with the disparity, as Motto is clearly a talented and knowledgeable guy, and I would like to imagine that I know what I'm doing/where I'm going (now and then... ...other times it's head-first learning)?

其实答案很简单,和一些叔叔鲍勃和克罗克福德爵士将双方捂脸,由于疏忽:

The answer is actually quite simple, and something Uncle Bob and Sir Crockford would both facepalm, due to the oversight:

把它清理干净

clean it up.

function toArray (arrLike) { // or asArray(), or array(), or *whatever*
  return [].slice.call(arrLike);
}

var checked = toArray(checkboxes).filter(isChecked);
checked.forEach(listValues);

现在,如果你质疑你是否需要做到这一点,你自己,答案很可能是没有结果...
这个确切的事情是......每次(?)库高阶功能,这些天完成。结果
如果您使用lodash或下划线,甚至jQuery的,他们都将不得不采取一组元素,并执行一个动作n次的方法。结果
如果你不使用这样的事情,然后通过各种手段,编写自己的。

Now, if you're questioning whether you need to do this, yourself, the answer may well be no...
This exact thing is done by... ...every(?) library with higher-order features these days.
If you're using lodash or underscore or even jQuery, they're all going to have a way of taking a set of elements, and performing an action n-times.
If you aren't using such a thing, then by all means, write your own.

lib.array = (arrLike, start, end) => [].slice.call(arrLike, start, end);
lib.extend = function (subject) {
  var others = lib.array(arguments, 1);
  return others.reduce(appendKeys, subject);
};

更新ES6(ES2015)和超越

不仅是一个片() / 阵列() /等辅助方法,将会使生活更轻松谁想要就像他们使用数组(他们应该)使用列表,但对于谁拥有了相对不远的将来,还是在当今通天塔transpiling的ES6 +浏览器操作的奢侈的人,你有语言功能的人内置的,这使得这种类型的东西是不必要的。

Update for ES6(ES2015) and Beyond

Not only is a slice( )/array( )/etc helper method going to make life easier for people who want to use lists just like they use arrays (as they should), but for the people who have the luxury of operating in ES6+ browsers of the relatively-near future, or of "transpiling" in Babel today, you have language features built in, which make this type of thing unnecessary.

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 ];

超级干净,而且非常有用的。结果
查找在恢复 取值$ P $垫运营商;尝试一下在BabelJS网站;如果你的技术堆栈是为了在生产与巴贝尔和构建步骤中使用它们。

Super-clean, and very useful.
Look up the Rest and Spread operators; try them out at the BabelJS site; if your tech stack is in order, use them in production with Babel and a build step.

有没有很好的理由不能够使用非数组转换成阵列......只是不要让你的code乱七八糟的什么都不做的的粘贴同样丑陋行,无处不在。

There's no good reason not to be able to use the transform from non-array into array... ...just don't make a mess of your code doing nothing but pasting that same ugly line, everywhere.

这篇关于什么是[] .forEach.call()在JavaScript中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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