前端面試常見問題日??偨Y。
1:call ,apply,bind 相同點和不同點。
相同點:都是用來改變函數(shù)指向。
不同點:call 和 apply 都是立即執(zhí)行,bind 不是立即執(zhí)行。
call 和apply 的區(qū)別:call()方法接受的是若干個參數(shù)的列表,而apply()方法接受的是一個包含多個參數(shù)的數(shù)組。call的性能更高一些
function add(c, d){
return this.a + this.b + c + d;
}
var obj={a:1,b:2};
var a=10,b=20;// window 下的 a,b
//先執(zhí)行 add
add(5,6); //41
//使用 call
add.call(obj,5,6);//14
add.apply(obj,[5,6]);//14,傳參是數(shù)組
var m=add.bind(obj,5,6); //不是立即執(zhí)行
m();//14
add.bind(obj,5,6)() //14
源碼實現(xiàn)
-
calll
Function.prototype._call=function()
{
//獲取需要更換的 this
var context=Array.prototype.shift.call(arguments,1);
context=context|| window;
var func=this;
context[func.name]=func;
//執(zhí)行
let res=context[func.name](arguments);
//執(zhí)行完成后刪除
delete context[func.name];
return res;
}
-
apply
Function.prototype._apply=function()
{
//獲取需要更換的 this
var context=Array.prototype.shift.call(arguments,1);
context=context|| window;
var func=this;
context[func.name]=func;
if(!(arguments[0] && Array.isArray(arguments[0])))
{
throw new TypeError('arguments is not array');
}
//執(zhí)行
let res=context[func.name](arguments[0]?[...arguments[0]]:null);
//執(zhí)行完成后刪除
delete context[func.name];
return res;
}
-
bind
Function.prototype._bind=function(){
var context=Array.prototype.shift.call(arguments,1);
context=context|| window;
var func=this;
//返回一個函數(shù)
return function(){
var res= func.call(context,arguments);
return res;
}
}
-
執(zhí)行
var a=1,b=2;
function add(c) {
return (this.a+this.b+c);
}
var obj={a:3,b:4};
add._call(obj,4);//11
add._apply(obj,[4]);//11
var _add=add._apply(obj);
_add(4); //11