# 更简单的理解 apply , call

The first time I know `apply` was when I met this code:

``````Math.max.apply(null, [1, 2, 3, 4])
``````

As the mdn said,

The apply() method calls a function with a given this value, and arguments provided as an array (or an array-like object).

Note: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

Actually, in case above, `thisArg` has no influence which means code below also works:

``````Math.max.apply(undefined, [1, 2, 3, 4])
Math.max.apply(Math, [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 })
function fn() {
console.log(Array.prototype.slice.call(arguments))
}
fn(1, 2, 3, 4) //[1,2,3,4]
``````

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 }
obj.slice() //Uncaught TypeError: obj.slice is not a function
``````

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 })
let obj = { length: 2 }
obj.slice = Array.prototype.slice
obj.slice()
``````

And to help it easier to understand , you can remember it like:

``````method.call(thisArg, ...args)
//works like in most cases
thisArg.method = method
thisArg.method(...args)
//for apply
method.apply(thisArg, args)
//works like in most cases
thisArg.method = method
thisArg.method(...args)
``````

Wasn’t that easy ?

So, let get back to `Math.max.apply({}, [1, 2, 3, 4])`. You can remember it like:

``````let thisArg = {}
thisArg.max = Math.max
thisArg.max(...[1, 2, 3, 4])
``````

And more cases:

``````Object.prototype.toString.call([]) //"[object Array]"
let thisArg = []
thisArg.toString = Object.prototype.toString
thisArg.toString() //"[object Array]"
//while
[].toString()//""
``````

Or

``````;[' sd ', 1, 3].map(Function.prototype.call, String.prototype.trim) //['sd','1','3']
;[' sd ', 1, 3].map(function(...args) {
return String.prototype.trim.call(...args)
})
;[' sd ', 1, 3].map(function(...args) {
let thisArg = args[0]
thisArg.trim = String.prototype.trim
return thisArg.trim(...args.slice(1)) //Uncaught TypeError: thisArg.trim is not a function
})
``````

In the case above, it will got error because `args[0]` is `Primitive values`. You can’t call methods in `Primitive values`. But it can still help you understand.

#### 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
thisArg.Array = Array
thisArg.Array(undefined, undefined)
``````

Hope it’s easier to understand `apply` and `call`.

Original Post

angular+ionic 的app上拉加载更新数据实现方法

2017-03-07
js实现简单的可切换选项卡效果

2017-03-22

2017-03-27

2017-03-26

2017-03-27
JavaScript实现滑动到页面底部自动加载更多功能

2017-03-17

this关键字在c++，java中都提供了这个关键字，在刚开始学习时觉得有难度，但是只要理解了，用起来就方便多了，下面通过本篇文章给大家详解js里this关键字的理解。 关于this，是很多前端面试必考的题目，有时候在网上看到这些题目，自己...
2017-03-29

JavaScript 的原型对象总是让人纠结。即使是经验丰富的JavaScript专家甚至其作者，经常对这一概念给出很有限的解释。我相信问题来自于我们对原型最早的认识。原型总是与new, constructor 以及令人困惑的prototy...
2017-03-25
vue-video-player 更改视频源

2018-05-05
10条建议帮助你创建更好的jQuery插件

2017-03-23