this到底指向谁

在我们编写的类中我们希望this是指向该类的实例即对象时,我们确有时候会出错。下面让我讨论一下这个this
这里有this 呈现不同值的六种方式。

  • 它们分别是:
  1. 全局环境下的this
  2. 对象构造函数中的this
  3. 对象方法中的this
  4. 简单函数中的this
  5. 箭头函数中的this
  6. 事件监听器中的this
  • 在全局环境下this值global或者window
console.log(this)
  • 浏览器下为window,通常情况下在全局下不使用this

  • 对象构造函数中的this

class Human {
    constructor(name) {
        this.name = name //this指向实例对象
    }
}

var people = new Human('Bill')
console.log(people.name) //Bill,此时this是people

var student = new Human('Jason')
console.log(student.name) // Jason 此时this只student
  • 对象方法中的this
var o = {
    sayName() {
        console.log(this.name)
        console.log("this指向->", this)
    }
}

o.name = 'Bill'
o.sayName()

//Bill
// this指向-> { sayName: [Function: sayName], name: 'Bill' }
  • 简单函数中的this
function sayName() {
    console.log(this) //window
}

因为sayName我们是在全局作用域内所以里面的this事全局环境下的

  • 思考下面的代码
var o = {
    doSomethingLater () {
      setTimeout(function() {
        this.speak() // Error
      }, 1000)
    },
    speak() {
      console.log("Hello Boy")
    }
  }

  o.doSomethingLater() //TypeError: this.speak is not a function
  • setTimeout函数中的回调函数是在全局作用域上所以里面的this是指向window的
  • 我们知道doSomethingLater实在对象o的作用域内的,那么我们就可以使用这个this,来替换下面的this
var o = {
    doSomethingLater () {
        var that = this //这个this是指向o的
      setTimeout(function() {
        that.speak()
      }, 1000)
    },
    speak() {
      console.log("Hello Boy")
    }
  }

  o.doSomethingLater() //Hello Boy
  • 使用es6中的箭头函数也可以解决上面的问题
  • 箭头函数中的this总是它定义时所指向的环境。
class Increment {
    constructor(i) {
        this.i = i
    }

    print() {
        setInterval(handlerCallback, 1000) //Uncaught ReferenceError: handlerCallback is not defined //此时是在全局作用域上查找handlerCallback的定义
    }

    handlerCallback() {
        console.log(this.i ++)
    }
}

var time = new Increment(0)
time.print()
  • 第三种在任意函数内改变this值的方式是使用bind, call 或 apply方法。我们在也经常使用bind来进行this的绑定
class Increment {
    
    constructor(i) {
        // debugger 打开这个可以在浏览器里调试
        this.i = i
    }

    print() {
        setInterval(this.handlerCallback, 1000) //这个this是指当前对象,在当前作用域查找handlerCallback的定义handlerCallback里是用了this.i
    }

    handlerCallback() {
        console.log(this.i ++) // 这个this指向了全局此时的i也被是全局的了
    }
}

var time = new Increment(0)
time.print() //NaN
  • 使用bind绑定
class Increment {
    
    constructor(i) {
        // debugger 打开这个可以在浏览器里调试
        this.i = i
    }

    print() {
        setInterval(this.handlerCallback.bind(this), 1000) //这句话的意思是handlerCallback函数里的this是指向当前对象的
    }

    handlerCallback() {
        console.log(this.i ++)
    }
}

var time = new Increment(0)
time.print() //1,2,3.....

到这里是否明白了this的含义了吗,要结合我们上篇的作用域理解效果更佳

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容