call()包含两个参数,第一个是要改变的this指向,第二个是真正的实参,用于函数的继承复用。
目标:编写myCall()实现和call一样的效果
//有两个对象obj和obj2,用myCall调用obj的fun打印出obj2的name和num var obj = { fun: function(arg){
var num = 0
arg.forEach(function(val){
num += val
} return this.name + num } } var obj2 = { name:'obj2的name' } console.log(obj.fun.myCall(obj2,1,2,2))
思路:
1、在Function原型下挂载myCall
2、判断this是否是函数,若不是抛出错误
3、将this赋值给传入的对象,注意this是一个函数
4、...arguments接收所有实参,并用splice(1)剔除第一个对象
5、调用新函数,赋值给常量res,删除新函数,返回res
实现:
Function.prototype.myCall = function(context) { //判断是否为函数 if(typeof this !== 'function'){ throw new TypeError('Error') } //context若是空值则指向window context = context || window //接收除对象外的实参 const arg = [...arguments].splice(1) //将this赋给传进来的对象,this是一个函数 context.fn = this //调用对象中的新方法,返回值给res const res = context.fn(arg) //this指向改变,方法执行完毕后,删除该方法 delete context.fn return res }
输出:
obj2的name5