# 使用场景

  • 全局执行环境,this指向全局对象(浏览器中是window

    this.test = 'test'
    console.log(this.test === window.test) // true
    console.log(this === window) // true
    
  • 函数作为对象的方法被调用时,它的this为调用该函数的对象(就近原则)

    const person = {
        name: 'lisi',
        say: function() {
            console.log(`I am ${this.name}`)
        }
        son: {
            name: 'lilong',
            say: function() {
                console.log(`I am ${this.name}`)
            }
        }
    }
    person.say() // I am lisi
    person.son.say() // I am lilong, 就近原则,say方法体内this为son对象
    
  • 函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。

    function Person(name, age) {
        this.name = name
        this.age = age
        this.toString = function() {
            console.log(`I am ${this.name}`)
        }
    }
    const person = new Person('lisi', 20)
    console.log(person.name) // lisi
    
  • 箭头函数体内的this对象,与封闭词法环境的this保持一致,指向固定,无法改变

    • 代码示例
      var name = 'window'
      const person = {
          name: 'lisi',
          say: () => {
              console.log(`I am ${this.name}`)
          }
      }
      const son = {
          name: 'lilong'
      }
      person.say()  // I am window
      person.say.call(son)   // I am window
      person.say.apply(son)   // I am window
      person.say.bind(son)()  // I am window
      
      对象不构成封闭词法环境,导致say箭头函数定义时的作用域就是全局作用域,所以this指向了window
    • 特点
      • 不可以使用arguments对象
      • 不可以当作构造函数,不能用作Generator函数
      • 没有自己的this,与创建时封闭词法环境的this保持一致
      • this指向固定,无法改变
  • 当函数被用作事件处理函数时,它的this指向触发事件的元素

# 使用注意事项

  • 避免多层this
    var o = {
        f1: function () {
            console.log(this === o)
            var f2 = function () {
                console.log(this === window)
            }()
        }
    }
    o.f1() // true, true
    var o1 = {
        f1: function () {
            console.log(this === o1);
            var f = () => {
                console.log(this === o1);
            }
            f()
        }
    }
    o1.f1()  // true, true
    
  • 避免数组处理方法中的this
    const arr = [1]
    arr.forEach(function(ele) {
        console.log(ele, this)  // 1, window
    })
    arr.forEach(function(ele) {
        console.log(ele, this)  // 1, arr
    }, arr)
    arr.forEach((ele) => {
        console.log(ele, this)  // 1, window
    }, arr)
    

# 固定this指向

# 参考文章