{this}关键字如何在map和call中工作?

问题描述

我一直在刷新关于call()map()NodeList用法的JavaScript知识。

通过Google进行搜索非常容易,call()应该做些什么,并且有一些资源说明了如何与map()一起使用。

但是,正如我在MDN上注意到的那样,map()函数也可以使用第二个参数,该参数应该为this设置map()关键字-至少我就是这样认为应该这样做。

我试图用简单的数组自己检查一下:

var numbers = [1,2,3];
var letters = ['a','b','c'];

..并且具有一个简单的功能,即将作为map()的参数:

var effector = function (x) {
    console.log(x);
}

现在,我不明白的是为什么这两个函数调用具有不同的结果:

numbers.map(effector,letters);
numbers.map.call(letters,effector);

我希望它们都向控制台输出字母,因为两个this关键字都应引用它们(分别引用它们的对象)。

我做了一些进一步的研究,并尝试使用这种修饰的效应子功能:

var effector = function () {
    console.log(this);
}

..再次:

numbers.map(effector,effector);

假设我们处于“严格使用”状态,则第一个通话记录为letters,第二个通话记录为undefined

但是同样,我希望这两个调用都能产生相同的输出。

我想念什么?

编辑:

我正在阅读.map可以如何进行填充,如果在MDN上进行检查,就会看到callback.call()中如何使用.map的第二个参数。

我想,最后,即使callback.call()也应与this中的.map相同。

MDN - map

解决方法

这里this引用有两个绑定:

  • this用于map函数的执行上下文
  • this用于回调函数的执行上下文

它们彼此不相关。

map的第二个参数指示用于回调的this。如果未提供,则默认值为undefined(而不是数组)。

map.call的第一个参数指示thismap的含义-并因此迭代哪个数组。

这也反映在mdn上提供的polyfill中:完全符合以下规范:O获得this函数的map值, T获得回调的this值。它们通常是不同的。

mapforEach

与您的问题无关,但值得一提:当您实际上没有映射任何内容时,请不要使用mapmap用于创建一个新数组,该数组中的每个值都通过在同一索引的原始值上调用回调函数来映射到每个值。

但是,当您只需要迭代数组值而无意执行此类映射时,请使用forEach方法或for...of循环。两者都可以直接在NodeList上使用,而无需.call

,

numbers.map(effector,letters)numbers.map.call(letters,effector)之间的区别在于哪个功能 this设置为letters

在第一个中,如MDN所述,第二个参数是在回调中用作this的值-即提供给map的参数。也就是说,在numbers.map(effector,letters)中,this内的effector将是letters。由于effector(在第一个版本中)并不关心this是什么,因此该参数基本上无效,并且记录了numbers的内容。

另一方面,在numbers.map.call(letters,effector)中,numbers.map的{​​{1}}设置为this。实际上,这意味着letters方法尽管被map调用,但是却被“劫持”以记录numbers的条目。

第二个示例的工作原理类似-关键是哪个{em>函数设置了letters:在一种情况下设置this,在另一种情况下设置effector

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...