思路解析
步骤: 同call,不同的是apply只接收两个参数:要调用的函数和参数数组,因此函数形参略有不同,...args改成args,并且加一个类型判断,判断args是否是Array实例。
- 首先明确apply函数是定义在Function.prototype上的,为所有Function类型的对象所共享。现自定义Function.prototype.myApply。
传入的参数: (1) context表示谁来调用这个原函数, (2) args表示参数数组;
- 1、判断args的类型,如果不是Array的实例,抛出一个TypeError;
- 2、确定由谁来调用函数,命名为new_this;若没有传入要绑定的对象, 默认绑定window对象;
- 3、把方法作为对象的属性绑定给new_this,但要注意,也许原有属性就有func这个属性,为了避免冲突,这里用了symbol;
- 4 、执行当前函数,并获取返回值;
- 5、 删除我们绑定的的Symbol(func)属性,以免污染new_this的属性;
- 6、返回第3步得到的返回值
// 先给Function原型尚扩展个方法并接收2个参数
Function.prototype.myApply = function(context,args){
// 默认不传就是window,可以用es6给参数设置默认参数
context = context || window
args = args ? args :[]
// 给context新增一个独立无二的属性以免覆盖原有属性
const key = Symbol()
// 通过隐式绑定的方式调用函数
const result = context[key](...args)
// 删除添加的属性
delete context[key]
// 返回函数调用的返回值
return result
}