Javascript中this的指向问题

159 阅读2分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

Javascript中的this

  • 面向对象语言中 this 表示当前对象的一个引用
  • 但在 JavaScript 中 this 不是固定不变的,函数中的 this 是在调用时绑定的,完全取决于函数调用的位置,即函数执行的上下文环境

this的四种绑定方式

默认绑定

  • 默认情况下,调用一个全局函数,函数的上下文是全局对象,因此 this 指向全局 window
var a = 123
function foo() {
    console.log(this.a)
}

foo() // 123
  • 严格模式下 this 指向 undefined
var a = 123
function foo() {
    "use strict"
    console.log(this.a)
}

foo() // ncaught TypeError: Cannot read properties of undefined (reading 'a')

隐式绑定

  • 在对象中的某个属性的值是函数的引用,当调用该属性 obj.fn(),此时的 this 指向对象的实例
var a = 123
function foo() {
    console.log(this.a)
}
var obj = {
    a: 'i am from obj',
    fn: foo
}

obj.fn() // 'i am from obj'
  • 隐式丢失:将 obj.fn 再赋值给另一个变量,再通过该变量调用,此时等于该变量直接引用了函数,执行函数的上下文为当前变量所在的上下文即全局的 a
var a = 123
function foo() {
    console.log(this.a)
}
var obj = {
    a: 'i am from obj',
    fn: foo
}
var b = obj.fn

b() // 123

显式绑定

  • 通过 apply call bind 修改 this 的指向
var a = 123
function foo() {
    console.log(this.a)
}
var obj = {
    a: 'i am from obj'
}

foo() // 123
foo.call(obj) // 'i am from obj'
foo.apply(obj) // 'i am from obj'
foo.bind(obj)() // 'i am from obj'

new绑定

  • new可以创建一个构造函数的实例,会返回一个新的对象,构造函数中的 this 指向这个新的对象
function foo( a){
  this.a = a
}
var b = new foo(123)

b.a // 123

四种绑定方式的优先级

  • new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

箭头函数中的this

  • 在箭头函数中,this 总是指向词法作用域,也就是指向外层
var a = 123
var obj = {
    a: 'i am from obj',
    fn: () => console.log(this.a),
}

obj.fn() // 123
  • 这里的箭头函数 arrFnout 函数中,因此 arrFnthis 指向外层 out,也就是 obj 对象
var a = 123
var obj = {
    a: 'i am from obj',
    out: function() {
        var arrFn = () => console.log(this.a)
        arrFn()
    }
}

obj.out() // 'i am from obj'