首先来了解apply的用法:
function fn(name){
console.log(`${name} ${this.msg}`)
}
const obj = {
msg: 'Hello World'
}
fn.apply(obj, ['Ksmith'])
// Ksmith Hello World
原生实现
Function.prototype.apply = function(context = window, args) {
// 第二参数如果不是一个对象的话
if (!(args instanceof Object)) {
throw new TypeError('CreateListFromArrayLike called on non-object')
}
// 除了数组以外的对象,都为空,也就是无参数
// 主要是为了跟原生表现一致
if(!(args instanceof Array)) {
args = []
}
// context如果没传是window
// 但如果传了,但并非是对象,怎么办?比如:String,Boolean等,但不包含Array、Function等
context = context instanceof Object ? context : {}
// 在上下文中执行fn方法,保证执行环境是context
context.fn = this
const result = context.fn(...args)
// 原生call是不会污染context的,所以这里要删除掉
delete context.fn
// 返回执行结果
return result
}