一定鸟、作用
call、apply、bind作用是改變函數(shù)執(zhí)行時的上下文伙单,簡而言之就是改變函數(shù)運(yùn)行時的this指向
那么什么情況下需要改變this的指向呢?下面舉個例子
var?name="lucy";
const?obj={
????name:"martin",
????say:function(){
????????console.log(this.name);
????}
};
obj.say();?//martin哈肖,this指向obj對象
setTimeout(obj.say,0);?//lucy吻育,this指向window對象
從上面可以看到,正常情況say方法輸出martin
但是我們把say放在setTimeout方法中淤井,在定時器中是作為回調(diào)函數(shù)來執(zhí)行的布疼,因此回到主棧執(zhí)行時是在全局執(zhí)行上下文的環(huán)境中執(zhí)行的,這時候this指向window币狠,所以輸出luck
我們實(shí)際需要的是this指向obj對象游两,這時候就需要該改變this指向了
setTimeout(obj.say.bind(obj),0);?//martin,this指向obj對象
二漩绵、區(qū)別
下面再來看看apply贱案、call、bind的使用
apply
apply接受兩個參數(shù)止吐,第一個參數(shù)是this的指向宝踪,第二個參數(shù)是函數(shù)接受的參數(shù),以數(shù)組的形式傳入
改變this指向后原函數(shù)會立即執(zhí)行碍扔,且此方法只是臨時改變this指向一次
functionfn(...args){
????console.log(this,args);
}
let?obj?=?{
????myname:"張三"
}
fn.apply(obj,[1,2]);?// this會變成傳入的obj瘩燥,傳入的參數(shù)必須是一個數(shù)組;
fn(1,2)?//?this指向window
當(dāng)?shù)谝粋€參數(shù)為null蕴忆、undefined的時候颤芬,默認(rèn)指向window(在瀏覽器中)
fn.apply(null,[1,2]);?//?this指向window
fn.apply(undefined,[1,2]);?//?this指向window
call
call方法的第一個參數(shù)也是this的指向,后面?zhèn)魅氲氖且粋€參數(shù)列表
跟apply一樣套鹅,改變this指向后原函數(shù)會立即執(zhí)行站蝠,且此方法只是臨時改變this指向一次
functionfn(...args){
????console.log(this,args);
}
let?obj?=?{
????myname:"張三"
}
fn.call(obj,1,2);?// this會變成傳入的obj,傳入的參數(shù)必須是一個數(shù)組卓鹿;
fn(1,2)?//?this指向window
同樣的菱魔,當(dāng)?shù)谝粋€參數(shù)為null、undefined的時候吟孙,默認(rèn)指向window(在瀏覽器中)
fn.call(null,[1,2]);?//?this指向window
fn.call(undefined,[1,2]);?//?this指向window
bind
bind方法和call很相似澜倦,第一參數(shù)也是this的指向,后面?zhèn)魅氲囊彩且粋€參數(shù)列表(但是這個參數(shù)列表可以分多次傳入)
改變this指向后不會立即執(zhí)行杰妓,而是返回一個永久改變this指向的函數(shù)
functionfn(...args){
????console.log(this,args);
}
let?obj?=?{
????myname:"張三"
}
const?bindFn?=?fn.bind(obj);?//?this?也會變成傳入的obj?藻治,bind不是立即執(zhí)行需要執(zhí)行一次
bindFn(1,2)?//?this指向obj
fn(1,2)?//?this指向window
小結(jié)
從上面可以看到,apply巷挥、call桩卵、bind三者的區(qū)別在于:
三者都可以改變函數(shù)的this對象指向
三者第一個參數(shù)都是this要指向的對象,如果如果沒有這個參數(shù)或參數(shù)為undefined或null,則默認(rèn)指向全局window
三者都可以傳參雏节,但是apply是數(shù)組胜嗓,而call是參數(shù)列表,且apply和call是一次性傳入?yún)?shù)钩乍,而bind可以分為多次傳入
bind是返回綁定this之后的函數(shù)辞州,apply、call?則是立即執(zhí)行