Checking the redundant type for a function?

In the Polyfill Array.prototype.forEachjs mdn section, you can find the following check:

if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
}

In this particular case, why bother with checking the function? During my tests, calling a function directly gives the same behavior

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

This is actually a little worse with this type of string concatenation, because we can see "[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
+4
source share
3 answers

In this particular case, why bother with checking the function?

If the array is empty, there will be no attempt to call the function, but it still does not work .

[].forEach('foo')
Run code

There is also a difference for non-empty arrays when accessing an element has side effects:

let foo = {
    get [0]() {
        alert(1);
    }
};

Array.prototype.forEach.call(foo, …);
// alert shows up if the early type check is missing
+3
source

forEach , 15.4.4.18 Array.prototype.forEach:

  • O ToObject, this .
  • lenValue [[Get]] O "length".
  • len be ToUint32(lenValue).
  • IsCallable(callbackfn) - false, TypeError.
  • thisArg , T be thisArg; T be undefined.
  • k be 0.
  • , k < len[...]

polyfill , , callbackfn (4.), ( 7.). - , callbackfn ( , len 0).

+2

I just noticed that they obviously do not name callback, as I did ( callback()), but they do callback.call(), which no longer gives the same behavior and in this case it makes sense to ensure the object has a function of type.

// 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);
+1
source

Source: https://habr.com/ru/post/1695736/


All Articles