手动实现call(),apply(),bind()

134 阅读1分钟

实现call()

// this为调用函数    
// context是参数函数    
Function.prototype.myCall = function(context) {        
    // 判断调用者是否为函数        
    if(typeof this !== 'function'){  
          throw new TypeError('error') 
    }       
    // 不传参的话默认是window     
    context = context || window        
    // 新增fn属性,将值设置为需要调用的函数      
    context.fn = this      
    // 将arguments转化为数组将call的传参提取出来       
    const args = Array.from(arguments).slice(1)       
    // 传参调用函数     
    const result = context.fn(...args)     
    // 删除函数        
    delete context.fn        
    // 返回执行结果        
    return result    
}        
// 测试    
function print(age){        
    console.log(this.name + ' ' + age)    
}    
var obj = {        
    name:'kobe'    
}    
// 调用函数的call方法    
print.myCall(obj,1,2,3)

实现apply

Function.prototype.myApply = function(context) {        
    // 判断调用者是否是函数        
    if(typeof this !== 'function'){            
        throw new TypeError('error')        
    }        
    // 不传参默认为window        
    context = context || window        
    // 新增fn属性,将值设为需要调用的函数        
    context.fn = this        
    // 返回执行结果        
    let result         
    // 判断是否有参数传入        
    if (arguments[1]) {            
        result = context.fn(...arguments[1])        
    }else{            
        result = context.fn()        
    }        
    // 删除函数        
    delete context.fn        
    // 返回执行结果        
    return result    
}    
// 测试    
function print(age,age2,age3) {        
    console.log(this.name+ ' ' + age + ' ' +age2 + ' ' +age3)    
}    
var obj = {        
    name:'kobe'    
}    
print.myApply(obj,[1,2,3])

实现bind()

Function.prototype.myBind = function(context) {        
    // 判断调用者是否为函数        
    if(typeof this !== 'function'){            
        throw new TypeError('error')        
    }                
    context = context || window        
    // 截取传递的参数        
    const args = Array.from(arguments).slice(1)        
    // _this指向调用函数        
    context.fn = this        
    // 返回一个函数        
    return function Fn(){            
        return args.length>0 ? context.fn(...args) : context.fn();        
    }    
}    
// 测试    
let a = {        
    name: 'I am a',        
    sayName: function(out){            
        console.log(this.name+(out ? out:""));        
    }    
};    
let b = {        
    name: 'I am b'    
};    
a.sayName.myBind(b,['我是额外参数','参数2'])()

以上三种方法也参考了不少文章,手动实现这三个方法也是面试中必然会问道的,这三种方法还算简答明了,易理解