面試題:call、apply和bind的區(qū)別和原理及擴(kuò)展的高級(jí)運(yùn)用

前言

在面試的過程中,會(huì)有許多新問題出現(xiàn)來讓你拓展新的知識(shí),也會(huì)發(fā)現(xiàn)學(xué)習(xí)中忽略的點(diǎn)。

在前兩天的一次面試中,面試官就問了call、apply和bind的區(qū)別。事實(shí)上,我們也應(yīng)該領(lǐng)悟得到面試官更想問到的東西是什么,也就是拓展出來的東西。


call

call是所有函數(shù)都能調(diào)用的方法,是Function.prototype里的方法

作用
  1. 調(diào)用函數(shù)
  2. 改變this,作為第一個(gè)參數(shù)
  3. 傳遞參數(shù),第二個(gè)參數(shù)之后的所有個(gè)數(shù)的參數(shù)
案例
function fn1(){
    console.log(1);
}
function fn2(){
    console.log(2);
}
fn1.call(fn2); //輸出 1
fn1.call.call(fn2); //輸出 2

解析
第一行輸出,調(diào)用了fn1并將this指向fn2
第二行輸出,事實(shí)上,執(zhí)行的call()才是關(guān)鍵,這里就涉及了Function.prototype.call()的機(jī)制,它只是把.call()之前的代碼段當(dāng)作一個(gè)變量,將傳遞的代碼段指向this,則fn1.call指向了fn2,于是就相對(duì)于fn2.call(),只是這里傳遞的thiswindow

運(yùn)用
  • 繼承的方法

      function Father(uname,age){
          this.uname= uname;
          this.age=age;
      }
      Father.prototype={
          constructor:Father,
          sing:function(){
              console.log("唱跳rap");
          }
      }
      function Son(){
          Father.call(this,uname,age)
      }
      Son.prototype=new Father();
    

apply

apply同樣也是所有函數(shù)都能調(diào)用的方法,是Function.prototype里的方法

作用
  1. 調(diào)用函數(shù)
  2. 改變this
  3. 傳遞參數(shù),第二個(gè)參數(shù)之后的所有數(shù)組參數(shù)
與call的區(qū)別

apply第二個(gè)參數(shù)是Array,而call是將參數(shù)以個(gè)數(shù)的形式傳入

運(yùn)用
  • 運(yùn)用Math函數(shù)獲取最大值

      let arr=Array.of(2,42,56,89,1,24,56,22)
      let max=Math.max.apply(Math,arr)
      console.log(max);
    

bind

bind同樣也是所有函數(shù)都能調(diào)用的方法,是Function.prototype里的方法

作用
  1. 改變this
  2. 傳遞參數(shù),第二個(gè)參數(shù)之后的所有個(gè)數(shù)參數(shù)
  3. 返回新函數(shù)
與call、apply的區(qū)別

與前兩者的最大不同就是不會(huì)調(diào)用函數(shù)并且修改后返回新的函數(shù)

運(yùn)用
let btns=document.querySelectorAll("button")
for(let btn of btns){
    btn.onclick=function(){
        this.disabled=true;
        setTimeout(function(){
            this.disabled=false;
        }.bind(this),2000);
    }
}

上面的案例修改了定時(shí)器的this,同時(shí)不會(huì)調(diào)用函數(shù)。但事實(shí)上如果你用了箭頭函數(shù)的寫法,因箭頭函數(shù)的this是關(guān)乎上下文的this,因此會(huì)簡(jiǎn)單許多,這個(gè)案例意在給我們理解bind的用法,那么在下面附上箭頭函數(shù)的寫法

let btns=document.querySelectorAll("button")
for(let btn of btns){
    btn.onclick=function(){
        this.disabled=true;
        setTimeout(()=>{
            this.disabled=false;
        },2000);
    }
}
最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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