JavaScript 中的实例方法,大多定义在实例的原型对象上,比如 Array.prototype.push
String.prototype.match
Function.prototype.bind
等。当我们通过实例来调用这些方法的时候,方法作为实例的属性,调用方式为 arr.push(1, 2 ,3)
。我们可以利用 call
函数来改变调用这些实例方法的方式,例如改造之后的 push
方法的调用方式为 push(arr, 'red')
,将实例作为了方法的第一个参数。
以下代码是正常方式调用数组的 push
方法:
const arr = [] arr.push(1, 2, 3)
push
方法定义在 Array.prototype
对象上,arr.push()
本质上是在 arr
对象上调用 Array.prototype.push
方法,因此以上代码可以改写为以下代码:
const arr = []Array.prototype.push.call(arr, 1, 2, 3)
更进一步,call
方法定义在 Function.prototype
对象上,Array.prototype.push.call()
本质上是在 Array.prototype.push
这个函数对象上来调用 Function.prototype.call
方法,因此我们可以用 bind
来固定 Function.prototype.call
方法的 this
对象,使它指向 Array.prototype.push
函数对象。
const arr = []const push = Function.prototype.call.bind(Array.prototype.push) push(arr, 1, 2, 3)
这样一来,调用 push()
方法就相当于调用 Function.prototype.call.call(Array.prototype.push)
,也就相当于调用 Array.prototype.push.call()
方法了。至此,我们对 push
函数的的改造已经完成了。我们还可以利用该技巧来改造其他方法。
const slice = Function.prototype.call.bind(Array.prototype.slice) slice(arr, 0, 2)const match = Function.prototype.call.bind(String.prototype.match) match(str, /^\d+$/)const bind = Function.prototype.call.bind(Function.prototype.bind) bind(func, context)
作者:Karmack
链接:https://www.jianshu.com/p/fd76509e81d4