JavaScript中apply、call和bind區(qū)別與聯(lián)系

一、相似點(diǎn)

apply、call和bind

  1. 都是Function類(lèi)下prototype的共有函數(shù),即所有函數(shù)都有。

  2. 都是用于指定 調(diào)用該方法(apply、call和bind)的 函數(shù)(fn) 執(zhí)行的作用域

二、用法及區(qū)別

1. apply

color ='blue';
var obj = {color :'red'};

function fn(){
    console.log(this.color);
}

fn();
fn.apply(obj);

輸出結(jié)果

blue
red

兩種調(diào)用方式,fn()的作用域?yàn)槿?,因此輸出結(jié)果為blue
fn.apply(obj) 通過(guò)apply將fn執(zhí)行的作用域指定為obj,其執(zhí)行效果等同于

var obj = {
color :'red',

b:function fn(){
    console.log(this.color);
}

};

obj.b();

2. call

在介紹call之前,再看一個(gè)apply的例子

function sum(a,b){
    return a + b;
}

function callSumWithApply(a,b) {
    return  sum.apply(this,[a,b]);
}

function callSumWithCall(a,b){
    return sum.call(this,a,b);
}

console.log(callSumWithApply(1,2));
console.log(callSumWithCall(3,4));

輸出結(jié)果:

3
7

解析:

sum.apply(this,[a,b])
通過(guò)apply指定sum的執(zhí)行作用域?yàn)槿?,通過(guò)數(shù)組傳入?yún)?shù)列表,在sum執(zhí)行時(shí)再拆分?jǐn)?shù)組與參數(shù)順序一一對(duì)應(yīng)。(劃重點(diǎn)1)

sum.call(this,a,b)
通過(guò)call指定sum的執(zhí)行作用域?yàn)槿郑苯訉⒑瘮?shù)參數(shù)依次填入,傳入?yún)?shù)列表。call和apply的差異僅此而已。 (傳參差異)

3. bind

apply和call在調(diào)用后立即執(zhí)行,而bind會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例,其this值會(huì)被綁定到傳給bind()函數(shù)的值,該實(shí)例被調(diào)用后才執(zhí)行。

color ='red';
var p = {color:'blue'};

function colorOut() {
    console.log(this.color);
}

var colorBind = colorOut.bind(p);

colorBind();
colorOut();

輸出結(jié)果:

blue
red

三、一些算法巧解

將兩個(gè)數(shù)組元素合并,常規(guī)做法是:

var arrayA = ['q','w'];
var arrayB = [1,2];

var arrayC =arrayA.concat(arrayB);

console.log(arrayA,arrayB,arrayC);

輸出結(jié)果:[ 'q', 'w' ] [ 1, 2 ] [ 'q', 'w', 1, 2 ]
但原數(shù)組并沒(méi)有變,必須新建數(shù)組才能囊括二者。如果直接向數(shù)組arrayA中push數(shù)組arrayB,即:

arrayA.push(arrayB);

輸出結(jié)果:[ 'q', 'w', [ 1, 2 ] ]
因?yàn)檎{(diào)用push時(shí),是按參數(shù)項(xiàng)直接添加的,arrayB被當(dāng)做一個(gè)元素直接添加到數(shù)組中,出現(xiàn)數(shù)組中的數(shù)組,事與愿違。我們期望的方式是:

arrayA.push(1,2);

因此,可以借助apply方法(在二.2中 劃重點(diǎn)1處 有如下說(shuō)明 apply 通過(guò)數(shù)組傳入?yún)?shù)列表,在sum執(zhí)行時(shí)再拆分?jǐn)?shù)組與參數(shù)順序一一對(duì)應(yīng)):

arrayA.push.apply(arrayA,arrayB);

先指定push函數(shù)的的作用域?yàn)閷?duì)象arrayA,然后將數(shù)組arrayB當(dāng)做參數(shù)列表傳入?yún)?shù)
輸出結(jié)果為:[ 'q', 'w', 1, 2 ]
如前所述,如果調(diào)用call方法,則直接會(huì)把a(bǔ)rrayB當(dāng)做參數(shù)傳遞.

arrayA.push.call(arrayA,arrayB);

輸出結(jié)果[ 'q', 'w', [ 1, 2 ] ]

最后補(bǔ)充一下:

arrayA.push.apply(arrayA,arrayB);

第一個(gè)arrayA其實(shí)換成arrayB或者arrayC都是可行的,甚至用

[].push.apply(arrayA,arrayB)

也是沒(méi)問(wèn)題的。因?yàn)槲覀円氖莗ush方法,后面已經(jīng)通過(guò)apply指定了該push方法的作用域,因此這個(gè)push原本屬于哪個(gè)數(shù)組已經(jīng)不重要了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容