资讯专栏INFORMATION COLUMN

Easier Way to Understand apply and call in JS

Wildcard / 2796人阅读

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])
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 })
//help you do
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]"
//help you do this
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"]
//help you do
;[" sd ", 1, 3].map(function(...args) {
  return String.prototype.trim.call(...args)
})
//help you do
;[" 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99780.html

相关文章

  • The Power of Ten – Rules for Developing Safety Cri

    摘要:探测器的代码就是写的,真厉害 New Horizon 探测器的代码就是 JPL 写的,真厉害 http://pixelscommander.com/wp-content/uploads/2014/12/P10.pdf Gerard J. Holzmann NASA/JPL Laboratory for Reliable Software Pasadena, CA 91109 Mo...

    Muninn 评论0 收藏0
  • promise, async, await, execution order

    摘要: async can be transformed to promise. So, if we want to understand async, we have to understand promise first. Promise Normally, promise is easy to understand, especially when using like this: p...

    neuSnail 评论0 收藏0
  • 《JavaScript Web应用开发》作者Nicolas:恰巧,爱好变职业(图灵访谈)

    摘要:本文仅用于学习和交流目的,不得用于商业目的。今年,我们依然会组织。随着语言的发展,这种情况将不再适用。本系列主要讨论如何获得这些高度模块化的应用程序。这一系列内的后续图书会讨论测试及部署等内容。更多精彩,加入图灵访谈微信 本文仅用于学习和交流目的,不得用于商业目的。非商业转载请注明作译者、出处,并保留本文的原始链接:http://www.ituring.com.cn/art... 访谈...

    wawor4827 评论0 收藏0
  • 5 ways to find code online

    5 Ways to find code online In 2015 google and the university of Nebraska published a research titled How developers search for code: A case study. This research was conducted on real google developers...

    _ipo 评论0 收藏0
  • Life of a Pixel 2018

    摘要:将操作记录为一列。在列表上进行操作被称为光栅化。能够运行产生位图的命令加速光栅化注意到此时像素并不在屏幕上。因此,线程将划分为。根据与的距离确定的优先级。被包装在一个中,该对象被提交给浏览器进程。 This talk is about how Chrome turns web content into pixels. The entire process is called rend...

    Miracle 评论0 收藏0

发表评论

0条评论

Wildcard

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<