apply
满足条件
1.把第一个参数绑定到调用myApply的function运行时的this;
2.第二个参数应与调用myApply的function的arguments内容一致;
3.严格模式和非严格模式第一个参数为null或undefined时情况要与apply函数一致;
代码
Function.prototype.myApply = function(){
var context,arr;
//谁调用的myApply this就指向谁
if(typeof this !== 'function'){
throw Error('typeof this !== "function"');
}
context = arguments[0];
arr = arguments[1] ? arguments[1] : [];
if(typeof context === 'undefined' || context === null){
//满足条件3
context = (function(){
return this;
}());
}
if(typeof context === 'undefined'){
this(...arr);
}else{
context.f = this;
context.f(...arr);
}
}
call
满足条件
1.把第一个参数绑定到调用myCall的function运行时的this;
2.除第一个参数外其余参数组成的数组应与调用myCall的function的arguments内容一致;
3.严格模式和非严格模式第一个参数为null或undefined时情况要与call函数一致;
代码
Function.prototype.myCall = function(){
var context,arr;
//谁调用的myCall this就指向谁
if(typeof this !== 'function'){
throw Error('typeof this !== "function"');
}
context = arguments[0];
//差异点 call与apply的传值方式所致
arr = [...arguments].slice(1);//手动转型
if(typeof context === 'undefined' || context === null){
//满足条件3
context = (function(){
return this;
}());
}
if(typeof context === 'undefined'){
this(...arr);
}else{
context.f = this;
context.f(...arr);
}
}
bind
满足条件
1.把第一个参数绑定到调用myBind的function运行时的this;
2.将除第一个参数外其余参数与function中参数合并;
3.严格模式和非严格模式第一个参数为null或undefined时情况要与bind函数一致;
代码
Function.prototype.myBind = function(){
var context,arr,_self;
//谁调用的myBind this就指向谁
if(typeof this !== 'function'){
throw Error('typeof this !== "function"');
}
context = arguments[0];
arr = [...arguments].slice(1);//手动转型
if(typeof context === 'undefined' || context === null){
//满足条件3
context = (function(){
return this;
}());
}
_self = this;
return function(){
if(typeof context === 'undefined'){//严格模式
_self(arr.concat(...arguments));
}else{
context.f = _self;
context.f(arr.concat(...arguments));
}
}
}