为什么我不能使用 getElementById 作为对 Array#map 的回调?

Why can I not use getElementById as a callback to Array#map?

要将字符串化数字数组映射到实际数字,我可以简单地传递 Number 函数:

let arr = ["0", "1", "-2.5"];

console.log(arr.map(Number));

现在我想使用与 document.getElementById 相同的方法将 id 字符串列表映射到它们对应的 DOM 节点:

let arr = ["a", "b"];

console.log(arr.map(document.getElementById));
<div id="a">a <span id="b">b</span></div>

这给了我

"TypeError: 'getElementById' called on an object that does not implement interface Document."

有人可以解释错误吗?

实验中,似乎与 this 在将 document.getElementById 作为回调传递给 [=16= 时不再指向正确的上下文(应该是 document)有关], 所以明确地传递一个界限 getElementById 就可以了:

let arr = ["a", "b"];

console.log(arr.map(document.getElementById.bind(document)));
<div id="a">a <span id="b">b</span></div>

不幸的是,这也违背了该方法的目的,即简洁,因为这可以从

缩短
arr.map(document.getElementById.bind(document))
// to
arr.map(id=>document.getElementById(id))

你可以找到正在发生的事情的解释here:

When this error is thrown, a function (on a given object), is called with a this not corresponding to the type expected by the function.

This issue can arise when using the Function.prototype.call() or Function.prototype.apply() methods, and providing a this argument which does not have the expected type.

This issue can also happen when providing a function that is stored as a property of an object as an argument to another function. In this case, the object that stores the function won't be the this target of that function when it is called by the other function. To work-around this issue, you will either need to provide a lambda which is making the call, or use the Function.prototype.bind() function to force the this argument to the expected object.

我还添加了我的替代解决方案:有an overload of the method map that allows you to set the context in the second parameter:

let arr = ["a", "b"];

console.log(arr.map(document.getElementById, document));
<div id="a">a <span id="b">b</span></div>