JavaScript之call()、apply()、bind() 詳解!

 作爲一名合格的前端開發者,大家都知道JavaScript中的this指向問題是一件很苦惱的事情,因爲你稍不留意他就跳來跳去 很多Bug就是在不經意間this上下文出錯導致。call()、apply()、bind()的作用也恰恰與this有關,因爲在項目開發中很少用到,大家只知道他們是爲了:“改變this指向”,但是這樣草草了事的答案,只會暴露出你對它們“根本不瞭解”!!OK,先來看一段簡單的代碼:

  //  window
  var name, age, love;
  function Create(name, age, love) {
      this.name = name
      this.age = age
      this.love = love
  }
  Create('王二牛', '18歲', '唱歌') //調用函數 Create()
  console.log(name, age, love)    //輸出結果 王二牛 18歲 唱歌

再此之前先了解call()函數的定義:

call():它可以用來調用所有者對象作爲參數的方法。通過 call(),能夠使用屬於另一個對象的方法。

首先,在window中定義了name age love三個變量,當執行Create()函數時 函數內部的this毫無疑問指向window,因爲他沒有具體指向調度者是誰,所以只能是window對象,其實此處調用相當於下面的寫法:

 Create.call(window, '王二牛', '18歲', '唱歌') //編譯器默認加上了call、並且指向window

然後,我們使用call()、()apply()函數改造一段改變this指向的代碼:注意第一個參數此刻不是window對象,而是Person對象,故this不再指向winodw。

  //  call 
  var name, age, love;
  var Person = {} //創建新對象

  function Create(name, age, love) {
      this.name = name
      this.age = age
      this.love = love
  }
  Create.call(Person, '王二牛', '18歲', '唱歌') //第一個參數指向Person對象
  console.log(Person) // 輸出結果 {name: "王二牛", age: "18歲", love: "唱歌"}

語法:call()、apply()函數的第一個參數都是this的指向,即調用者。第二個參數及其以後的所有參數都是Create函數的實參;

區別:call()第二個以及之後的若干參數可以是string、function、Array、object等,且可以有多個參數;

          apply()只能有兩個參數,並且實參只能以數組類型傳遞到調用函數內部,這也是兩者唯一的區別;


接着我們來看看bind()函數的作用:

bind():將函數綁定到某一個特定的對象上,調用函數內的this指向的值會被綁定到傳入bind()第一個參數的值,例如,f.bind(obj),實際上可以理解爲obj.f();

  //  bind
  var name = '張三瘋', age = 88;
  var obj = {
      name: '楊過',
      age: 18,
      sex: '男',
      fun: function () {
          console.log(this.name + " 今年" + this.age + "歲," + "性別:" + this.sex)
      }
  }
  var Girl = {
      name: "小龍女",
      age: 16,
      sex: "女"
  }
  obj.fun()   // 輸出結果 楊過 今年18歲,性別:男
  obj.fun.bind(window)() // 輸出結果 張三瘋 今年88歲,性別:undefined
  obj.fun.bind(Girl)()   // 輸出結果 小龍女 今年16歲,性別:女

述代碼,直接調用 obj.fun() 函數、內部的this指向了 obj 自身對象,因爲調度者是obj自身。

使用 bind 函數調用時 bind的第一個參數指向了 window 對象,即改變了 this 指向  window 中只定義了變量 name、age ,sex未定義,所以輸出結果爲“張三瘋 今年88歲,性別:undefined”。

第三次調用改變了this指向爲Girl對象,那麼她的小龍女就上場了。

注意: bind()除了返回是函數以外,它的參數和 call 一樣。


 如果我的博客幫助你解決了開發問題,請不要吝嗇你的小紅心哦!


 

發佈了17 篇原創文章 · 獲贊 85 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章