1. 撲朔迷離的 this 從錶面來看,this 總能通過各種變通的方式得到意想不到的結果 既然是“意想不到”,就說明對“各種變通的方式”不太瞭解 那麼我們來看看“各種變通的方式” 老早以前,this 指向它的調用者 1 <script> 2 // 通過 dom 調用 3 var _html = d ...
1. 撲朔迷離的 this
-
從錶面來看,this 總能通過各種變通的方式得到意想不到的結果
-
既然是“意想不到”,就說明對“各種變通的方式”不太瞭解
-
那麼我們來看看“各種變通的方式”
- 老早以前,this 指向它的調用者
1 <script> 2 // 通過 dom 調用 3 var _html = document.documentElement; 4 _html.onclick = function () { 5 console.log("this === _html", this === _html); // true 6 }; 7 8 // 通過 obj 調用 9 var _obj = { 10 getInfo: function () { 11 console.log("this === _obj", this === _obj); // true 12 }, 13 }; 14 _obj.getInfo(); 15 16 // 直接調用 17 function getInfo() { 18 console.log("this === window", this === window); // true 19 } 20 getInfo(); 21 </script>
- 後來遇到了面試官,學會了 bind
1 <script> 2 // 預定義一個 dom 和 handle 3 var _html = document.documentElement; 4 function handle() { 5 console.log(this); 6 } 7 8 // 預定義調用者 9 var _num = 1; 10 var _obj = {}; 11 var _nul = null; 12 13 // 使用 bind 綁定 14 var _numHandle = handle.bind(_num); 15 var _objHandle = handle.bind(_obj); 16 var _nulHandle = handle.bind(_nul); 17 18 // 都執行一遍 19 _html.addEventListener("click", _numHandle); // Number {1} 20 _html.addEventListener("click", _objHandle); // {} 21 _html.addEventListener("click", _nulHandle); // Window {…} 22 </script>
- 後來發現,如果獨立調用一個函數,使用 bind 太麻煩了,學會了 call,apply,我下麵用 call
1 <script> 2 function getInfo() { 3 console.log(this); 4 } 5 6 // 預定義調用者 7 var _num = 1; 8 var _obj = {}; 9 var _nul = null; 10 11 // 用 call 調用 12 getInfo.call(_num); // Number {1} 13 getInfo.call(_obj); // {} 14 getInfo.call(_nul); // Window {…} 15 </script>
- 可以看到 [call, apply, bind] 綁定 this 的時候對參數做了處理,如果是 null 或 undefined,就綁定 window;如果是簡單數據類型,就用 Object 包裹一下
- 老早以前,this 指向它的調用者
2. 通過以上經驗做一個推理
- this 本來指向它的調用者
- 通過 [call, apply, bind] 可以改變 this 指向
- 有沒有可能是改變了“調用者”,所以 this 指向了新的“調用者”
- 這裡是我的另一篇文章,手動實現 [call, apply, bind],它的實現方式就是改變“調用者”
- 可以嘗試手動實現箭頭函數
3. 結論
- this 指向調用者
- 改變 this 指向的方式是改變調用者
- 一路走來,真是返璞歸真啊^O^