对apply,bind ,call进行第二次封装,首先要知道这三个的作用和区别,下面先给大家叙述一下这三者的区别和作用
这三者都是改变this的指向问题,都是Functuon的prototype的一个方法。
区别:call和bind传参需要枚举出来,用逗号隔开。而apply的传参是以数组的形式来传参。
下面是我对这三个简单的封装
call的封装
Function.prototype.newCall=function(){
// 判断传递的第一个参数,如果为空或者undefined就用window调用
var ctx=arguments[0]||window
ctx.fn=this
var args=[]
arguments.foreach(item=》{
args.push(item)
})
var result=eval(‘ctx.fn(’+args.join(‘,’)+‘)’)
delete ctx.fn
return result
}
apply 封装
Function.prototype.newApply=function(ctx,arr){
var ctx=ctx || window
ctx.fn=this
if(!arr){
var result=ctx.fn();
delete ctx,fn;
return resulr
}else{
var args=[]
arr .foreach(item=》{
args.push(item)
})
var result=eval(‘ctx.fn(’+args.join(‘,’)+‘)’)
delete ctx.fn
return result
}
}
bind封装
Function.prototype.newBind=function(){
//截取第一个之后的所有参数
var args = [].slice.call(arguments, 1);
var self = this;
var temp = function () {};
var all = function () {
// 这个参数是bind返回的函数调用的参数
var bindarg = [].slice.call(arguments);
// 当作为构造函数时,this指向实例,此时 this instanceof fBound结果为true
// 当作为普通函数时,this指向window,此时结果为false,将绑定函数的this指向ctx。
return self.apply(this instanceof all ? this : ctx, args.concat(bindarg))
}
// 修改返回函数的prototype为绑定函数的prototype,实例就可以继承绑定函数的原型中的属性
temp.prototype = this.prototype;
all.prototype = new temp();
// 将fBound.prototype赋值为空对象的实例(原型式继承)
return all;
};