在Array.prototype.forEach
js mdn的Polyfill部分,您可以找到以下检查:
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
在这种特殊情况下,为什么还要检查功能?在我的测试中,直接调用函数会产生完全相同的行为
var callback;
callback();
// Uncaught TypeError: callback is not a function
var callback = "";
callback();
// Uncaught TypeError: callback is not a function
var callback = 2;
callback();
// Uncaught TypeError: callback is not a function
var callback = [];
callback();
// Uncaught TypeError: callback is not a function
var callback = {};
callback();
// Uncaught TypeError: callback is not a function
实际上这种类型的字符串连接有点糟糕,因为我们可能会看到"[object Object] is not a function"
:
function newCallback(val){
if (typeof val !== 'function') {
throw new TypeError(val+ ' is not a function');
}
}
newCallback({});
//Uncaught TypeError: [object Object] is not a function
答案 0 :(得分:3)
在这种特殊情况下,为什么还要检查功能?
如果数组为空,则不会尝试调用该函数,而是should still fail。
[].forEach('foo')
当元素访问具有副作用时,非空数组也存在差异:
let foo = {
get [0]() {
alert(1);
}
};
Array.prototype.forEach.call(foo, …);
// alert shows up if the early type check is missing
答案 1 :(得分:2)
forEach的行为是以15.4.4.18 Array.prototype.forEach:
的方式定义的
- 让
O
成为调用ToObject
传递this
值作为参数的结果。- 让
lenValue
成为使用参数[[Get]]
调用O
"length"
内部方法的结果。- 让
len
成为ToUint32(lenValue)
。- 如果
IsCallable(callbackfn)
为false
,则抛出TypeError
例外。- 如果提供了
thisArg
,请T
为thisArg
;其他请T
为undefined
。- 让
k
成为0
。- 重复,同时
醇>k
<len
[...]
因为polyfill是根据规范实现的,所以callbackfn
是一个函数( 4。)的测试必须在迭代开始之前完成( 7。 强>)。因此,即使未调用callbackfn
,也会抛出错误(在len
为0
的情况下)。
答案 2 :(得分:1)
我只是注意到他们没有像我做的那样明确地调用callback
(callback()
)而是他们callback.call()
,它们不再产生相同的行为,在这种情况下有意义的是确保对象具有类型函数。
// Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);