Array.prototype.map.call vs Array.map

时间:2017-08-08 09:32:08

标签: javascript arrays dom

我正在阅读querySelector方法,文章建议例如使用Array.prototype.map.call()代替map()。我对此没有任何问题,但是我真的不明白为什么Array.prototype.map.call()应该选择Array.map()为什么一个比另一个好?

let nodes = document.querySelectorAll('div.menu-item')

Array.prototype.map.call(nodes, one => one.innerHTML)
//vs
Array.map(nodes, one => one.innerHTML)

2 个答案:

答案 0 :(得分:2)

首先,没有Array.map。前一种变体的用例如下:您无法通过map调用document.querySelectorAll('div')[0].map。这就是事实,document.querySelectorAll返回NodeList而不是数组而缺少map方法。

  

是什么让一个人比另一个好?

问题实际上不是更好的变体。它无法在NodeList上调用map

当以thisArg传递给call {{1}时,数组原型中的大多数函数也能够处理类似数组的对象(即,其键是数字索引表示的对象) Array.prototype.map.call(array-like,mapFunction)`可以像数组一样映射NodeList。

但是有两种选择:

  1. 使用ES6中引入的Array.from(or apply). Hence,,Internet Explorer不支持。但是,如果这无关紧要,我宁愿这样做。
  2. 使用Array.from(nodes, n => n.innerHTML),其效果类似(请参阅how does Array.prototype.slice.call() work?)或坚持使用Array.prototype.slice.call(nodes).map(n => n.innerHTML)
  3. 然而,根据你的整体代码,(1)的用法看起来非常好,而且我个人更喜欢这个。

答案 1 :(得分:1)

  

是什么让一个人比另一个好?

标准JavaScript库中没有Focused。因此,如果您使用它,则依赖于未指定的功能,该功能可能存在于所有目标环境中,也可能不存在。 (例如,Firefox的SpiderMonkey JavaScript引擎提供了它;在撰写本文时,Chrome的V8引擎不提供。)因此,在这两种选择中,选择<Style x:Key="ButtonStyle" TargetType="Button"> <Setter Property="Background" Value="Transparent" /> <Setter Property="Foreground" Value="Black" /> <Setter Property="FontWeight" Value="Normal" /> <Setter Property="FontSize" Value="40" /> <Setter Property="UseSystemFocusVisuals" Value="False" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid x:Name="RootGrid" Background="{TemplateBinding Background}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="PointerOver"> <VisualState.Setters> <Setter Target="FocusContentPresenter.FontWeight" Value="Bold" /> <Setter Target="ContentPresenter.FontWeight" Value="Bold" /> <Setter Target="ContentPresenter.Foreground" Value="Pink" /> </VisualState.Setters> </VisualState> <VisualState x:Name="Pressed"> <VisualState.Setters> <Setter Target="ContentPresenter.Foreground" Value="Purple" /> </VisualState.Setters> </VisualState> <VisualState x:Name="Disabled"> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="FocusStates"> <VisualState x:Name="Focused"> <VisualState.Setters> <Setter Target="FocusContentPresenter.Foreground" Value="Purple" /> <Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" /> </VisualState.Setters> </VisualState> <VisualState x:Name="PointerFocused"> <VisualState.Setters> <Setter Target="FocusContentPresenter.Foreground" Value="Purple" /> <Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" /> </VisualState.Setters> </VisualState> <VisualState x:Name="Unfocused" /> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" /> <ContentPresenter x:Name="FocusContentPresenter" Opacity="0" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> 是一个相当重要的理由。 : - )

但是ste2425 points out,考虑到您使用Array.map和箭头功能,您似乎正在为ES2015 +环境编码。在这种情况下(或者如果添加polyfill),您可以使用Array.from的映射功能:

Array.prototype.map.call

let从任何类似数组的对象或可迭代对象创建一个数组。来自let innerHTMLArray = Array.from(nodes, o‌​ne => one.innerHTML); 的{​​{1}}都是。 :-)并且它可以选择让你映射这些值。

示例:

Array.from
NodeList