The first time I know apply
was when I met this code:
Math.max.apply(null, [1, 2, 3, 4]) |
As the mdn shows, the syntax is:
function.apply( thisArg , [argsArray] )
Actually, in case above, thisArg has no influence which means code below also works:
Math.max.apply(undefined, [1, 2, 3, 4]) |
The only effect of apply
in the code above is that it can pass the values in array to the function max
. So, code above equal
Math.max(1, 2, 3, 4) |
Why would I mention this? Because we don’t need this anymore because we already have ...
which works like:
Math.max(...[1, 2, 3, 4]) |
The reason that we still need apply
and call
is the thisArg. They can help us call some powerful methods.
thisArg in apply and call
I guess you might have seen this code:
Array.prototype.slice.call({ length: 2 }) |
Today, we don’t need this either because of Array.from
. But I still want to talk about it for explanation. In the case above, call
was used because we want to do something like:
let obj = { length: 2 } |
It would cause error because slice was defined in Array.prototype
. Only Array
instance can call that method. But actually in the implementation of slice
, it doesn’t need to be called by Array
instance and there is a lot of methods like this. So, in this case, call
or apply
would let non Array
instance call these methods which means
Array.prototype.slice.call({ length: 2 }) |
And to help it easier to understand , you can remember it like:
method.call(thisArg, ...args) |
Wasn’t that easy ?
So, let get back to Math.max.apply({}, [1, 2, 3, 4])
. You can remember it like:
let thisArg = {} |
And more cases:
Object.prototype.toString.call([]) //"[object Array]" |
Or
;[' sd ', 1, 3].map(Function.prototype.call, String.prototype.trim) //['sd','1','3'] |
More in apply
As apply
can accept an array-like object. So, what would happen if coding like:
Array.apply(null, { length: 2 }) |
Actually, it equals
Array.apply(null, [undefined, undefined]) |
So, you can understand it like:
let thisArg = {} //set null would get error in code below, also thisArg in above case is not important |
Function.prototype.call.apply
You might have seen code using Function.prototype.call.apply
which seems a little weird. However, it still make sense, especially in ES5. For example,
var arrayLike = { 0: 0, length: 1 } |
which works like
let arrayLike = { 0: 0, length: 1 } |
also equal
let arrayLike = { 0: 0, length: 1 } |
which works like
let arrayLike = { 0: 0, length: 1 } |
|