apply
一道有意思的面试题
## 方法重用
通过 apply() 方法,您能够编写用于不同对象的方法。
apply函数在前端的世界里大家都耳熟能祥了
关于apply碰到了一道有意思的面试题记录下来。
我们先来看看这段代码:
function fn () {
console.log('hello this is apply)
}
fn.apply = function () {
console.log('调用apply')
}
上边这段代码当我们需要使用fn.apply的时候,想修改fn的this指向,应该如何做呢?
当我们平平常常(tianzhen)的来调用一下它的apply
fn.apply(null)
// 打印:调用apply
打印结果是调用apply,这个时候我们已经重写了fn上的apply方法,再次调用apply肯定调用的事我们重写后的apply函数,这个时候就犯了难了,我就是想要在这个情况下调用fn原本的apply函数,我们应该怎么做?
别着急往下看,尝试思考思考。
解决方式
基于原型思路方式
其实有两种解决方式,我们先来看看第一种。
有的同学可能已经猜到了,apply本质上是挂在Function.prototype上的方法。既然我们重写了函数本身的apply,而fn的apply也是通过原型去查找的。所以我们可以通过Function.prototype.apply获得fn函数原本的apply方法。
这个时候我们需要调用它就很简单了
Function.prototype.apply.call(fn,null,[1,2,3])
-
第一个参数
fn,是我们传递给方法Function.prototype.apply的this。这样的话就相当于fn.apply(此时的apply是原型上的apply方法)。 -
第二个参数
null,是call方法传递给apply方法的第一个参数,也就是规定的this指向。 -
第三个参数是一个数组,是传递给
apply方法的参数。
这样就可以通过原型的方式调用fn函数的apply方法,并且支持自定义this指向和传入指定参数。
Reflect
当然在Es6中有一种更简单的方式,就是直接使用Reflect.apply(fn)就可以直接达到想要的效果。
Reflect.apply(target, thisArgument, argumentsList)
Reflect.apply()
-
target
目标函数。
-
thisArgument
target函数调用时绑定的this对象。
-
argumentsList
target函数调用时传入的实参列表,该参数应该是一个类数组的对象。
Reflect.apply(fn, null, [1, 2, 3]);