JavaScript中的this关键字

145 阅读2分钟

this关键字产生的原因

为了能够在对象的方法上使用对象的属性,由于JavaScript的作用域机不支持此需求,所以产生了this机制

var obj = {
  prop: '属性',
  func: function() {
      console.log(this.prop)
  }
}

obj.func()

this的用法

this是和执行上下文绑定的, 每个执行上下文都有一个this,

执行上下文主要有三种:

  1. 全局执行上下文
  2. 函数执行上下文
  3. eval执行上下文

所以this也对应的有三种

全局执行上下文

浏览器中的全局执行上下文的this就是 window

this === window // true

函数执行上下文

'use strict'严格模式(JavaScript Modules自动启用严格模式)下 this指向 undefined

非严格模式下, this指向 window

改变this的指向的方法

  1. 通过callapplybind的方式
var obj2 = {prop: '新属性'}
obj.func.call(obj2) // 参数列表
obj.func.apply(obj2) // 包含多个参数的数组
obj.func.bind(obj2)() // bind仅仅绑定并不执行
  1. 通过对象调用的方法
obj.func() // '属性'

但是复制给一个全局对象,this又返回函数执行上下文默认的情况

var test = obj.func
test() // window 或者 TypeError: Cannot read property 'prop' of undefined
  1. 通过构造函数
var obj = {
  prop: '属性',
  func: function(args) {
    this.data = args
  }
}

var  test = new obj.func('AA')
console.log(test) // func { data: 'AA' }

构造函数new的原理就是

const tempObj = {}
obj.func.call(tempObj)
return tempObj

this的设计缺陷以及应对方案

  1. 嵌套函数的this不会从外层函数继承, this和变量不一样,没有作用域的限制
var obj = {
  prop: '属性',
  func: function() {
      function innerFunc() {
        console.log(this)
      }
      innerFunc()
  }
}

obj.func() // undefined

可以通过把this复制给that变量,通过变量的作用域机制传递给嵌套函数;通过箭头函数,箭头函数没有自己的执行上下文,它会继承调用函数中的this

  1. 普通函数中的this默认指向window, 这样会打破数据的边界

可以通过严格模式,或者自动开启严格模式的Javascript Modules的方式