搞懂 js 中 this 的指向(简洁易懂版)

94 阅读2分钟

想弄懂this的指向其实并不难,只需要记住最核心的一句话: 谁 '调用'我 , this就指向谁,说人话: this相当于中文中的'我',谁说出来这个字,这个字就代表谁

下面列举几种情况:

1.普通函数this指向window

         function fn(){
            console.log(this)
        }
        //(1)普通函数 
        fn()// this->window  这里其实是window.fn() 此处window可以省略不写 

2.对象函数调用 谁调用'我','我'就指向谁

    let obj = {
      name: "月月",
      fn: function () {
        console.log(this) // obj
      }
    }
    obj.fn()  //this -> obj  

3.构造函数 this指向new创建的实例对象

    function fn() {
      console.log(this)
    }
    //(2)构造函数
    new fn()//this->new创建的实例

4.事件绑定的方法, 此时this指向事件源

<body>
  <button>按钮</button>
  <script>
    document.querySelector('button').addEventListener('click', function () {
      console.log(this);  // this -> button
    })
  </script>
</body>

补充一点:箭头函数,在箭头函数里面是没有this的,因为箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this

最后再来说说修改函数内部this的 call() 和 apply() 和 bind()

    let obj = {
      name: "月月"
    }
    function fn(a, b) {
      console.log(this)
      console.log(a + b)
    }
    fn(10, 20)  //this -> window    30
    //(1) 函数名.call(修改的this,参数1,参数2………)
    fn.call(obj, 10, 20)  // this -> obj        a+b = 30

    //(2) 函数名.apply(修改的this, 数组/伪数组 )
    // apply会自动遍历数组和伪数组,然后逐一传参
    fn.apply(obj, [20, 30])   // this -> obj    a+b = 50
    //(3) 函数名.bind(修改的this)
    // bind不会立即执行函数,而是得到一个修改this之后的新函数
    let newFn = fn.bind(obj)  // this -> obj     a+b = 100
    newFn(50, 50)

关于call和apply和bind三者的区别

1.相同点: 都可以修改this指向

2.不同点:

(1)传参的方式不同:call是单个传参,apply是数组/伪数组传参

(2)执行的机制不同:call和apply会立即执行函数,bind不会立即执行而是得到this的新函数