1. 扑朔迷离的 this
-
从表面来看,this 总能通过各种变通的方式得到意想不到的结果
-
既然是“意想不到”,就说明对“各种变通的方式”不太了解
2. 那么我们来看看“各种变通的方式”
- 老早以前,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,就绑定 Window;如果是简单数据类型,就用 Object 包裹一下
3. 通过“各种变通的方式”做一个推理
- this 本来指向它的调用者
- 通过 [call, apply, bind] 可以改变 this 指向
- 有没有可能是改变了了“调用者”,所以 this 指向了新的“调用者”
- 这里是我的另一篇文章,手动实现 [call, apply, bind],它的实现方式就是改变“调用者”
- 可以尝试手动实现箭头函数
4. 结论
- this 指向调用者
- 改变 this 指向的方式是改变调用者
- 一路走来,真是返璞归真啊^O^