冗余类型检查功能?

时间:2018-04-04 05:26:51

标签: javascript typechecking

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

3 个答案:

答案 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

的方式定义的
  
      
  1. O成为调用ToObject传递this值作为参数的结果。
  2.   
  3. lenValue成为使用参数[[Get]]调用O "length"内部方法的结果。
  4.   
  5. len成为ToUint32(lenValue)
  6.   
  7. 如果IsCallable(callbackfn)false,则抛出TypeError例外。
  8.   
  9. 如果提供了thisArg,请TthisArg;其他请Tundefined
  10.   
  11. k成为0
  12.   
  13. 重复,同时k< len   [...]
  14.   

因为polyfill是根据规范实现的,所以callbackfn是一个函数( 4。)的测试必须在迭代开始之前完成( 7。 )。因此,即使未调用callbackfn,也会抛出错误(在len0的情况下)。

答案 2 :(得分:1)

我只是注意到他们没有像我做的那样明确地调用callbackcallback())而是他们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);