zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

关于 js 的 this 指向问题

2023-03-31 11:00:41 时间

一、复杂度

  • 这个问题本身并不复杂,通过穷举法很容易就能得到有限的结果

二、影响 this 指向的因素

  • this 的指向与函数行为有关,函数行为包括:定义,赋值,调用

三、经验性的概括

  1. 普通函数的 this 指向,只和调用方式有关
  2. 箭头函数的 this 指向,只和定义环境有关

四、举例说明

  1. 改变普通函数的调用者
     1 <script>
     2     // 定义一个方法
     3     const person = {
     4         getInfo() {
     5             console.log(this);
     6         },
     7     };
     8     // 把方法拿出来,定义一个顶级变量
     9     const getInfo = person.getInfo;
    10 
    11     person.getInfo(); // 调用者:person,this:person
    12     getInfo(); // 调用者:window,this:window
    13 </script>
  2. 改变箭头函数的调用者
     1 <script>
     2     // 定义一个方法
     3     const person = {
     4         getInfo: () => {
     5             console.log(this);
     6         },
     7     };
     8     // 把方法拿出来,定义一个顶级变量
     9     const getInfo = person.getInfo;
    10 
    11     person.getInfo(); // 定义环境:顶级作用域,this:window
    12     getInfo(); // 定义环境:顶级作用域,this:window
    13 </script>
  3. 改变箭头函数的定义环境
     1 <script>
     2     // 定义一个方法
     3     const person = {
     4         getInfo() {
     5             return () => console.log("person", this);
     6         },
     7     };
     8     // 把方法拿出来,定义一个顶级变量
     9     const getInfo = person.getInfo;
    10 
    11     person.getInfo()(); // 定义环境:person.getInfo,this:person
    12     getInfo()(); // 定义环境:window.getInfo,this:window
    13 </script>
  4. 复杂情况
     1 <script>
     2     // 定义一个方法
     3     const person = {
     4         getInfo() {
     5             // 定义环境:window.cat,this:window
     6             cat()();
     7             // 定义环境:person.cat,this:person
     8             cat.call(person)();
     9             return () => console.log("person", this);
    10         },
    11     };
    12     // 把方法拿出来,定义一个顶级变量
    13     const getInfo = person.getInfo;
    14 
    15     const cat = function () {
    16         return () => console.log("cat", this);
    17     };
    18 
    19     person.getInfo()(); // 定义环境:person.getInfo,this:person
    20     getInfo()(); // 定义环境:window.getInfo,this:window
    21 </script>
  5. [ call, apply, bind ] 不需要讨论,因为它们的原理就是改变调用者,我在这里实现了下

五、结尾

  • 可以看到,尽管面试题花里胡哨,但是万变不离其宗
  • 当然了,掌握好 this 指向,是为了我们能写出更好用的代码