this关键字产生的原因
为了能够在对象的方法上使用对象的属性,由于JavaScript的作用域机不支持此需求,所以产生了this机制
var obj = {
prop: '属性',
func: function() {
console.log(this.prop)
}
}
obj.func()
this的用法
this是和执行上下文绑定的, 每个执行上下文都有一个this,
执行上下文主要有三种:
- 全局执行上下文
- 函数执行上下文
- eval执行上下文
所以this也对应的有三种
全局执行上下文
浏览器中的全局执行上下文的this就是 window
this === window // true
函数执行上下文
在'use strict'严格模式(JavaScript Modules自动启用严格模式)下 this指向 undefined
在非严格模式下, this指向 window
改变this的指向的方法
- 通过
call、apply、bind的方式
var obj2 = {prop: '新属性'}
obj.func.call(obj2) // 参数列表
obj.func.apply(obj2) // 包含多个参数的数组
obj.func.bind(obj2)() // bind仅仅绑定并不执行
- 通过对象调用的方法
obj.func() // '属性'
但是复制给一个全局对象,this又返回函数执行上下文默认的情况
var test = obj.func
test() // window 或者 TypeError: Cannot read property 'prop' of undefined
- 通过构造函数
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的设计缺陷以及应对方案
- 嵌套函数的
this不会从外层函数继承,this和变量不一样,没有作用域的限制
var obj = {
prop: '属性',
func: function() {
function innerFunc() {
console.log(this)
}
innerFunc()
}
}
obj.func() // undefined
可以通过把
this复制给that变量,通过变量的作用域机制传递给嵌套函数;通过箭头函数,箭头函数没有自己的执行上下文,它会继承调用函数中的this
- 普通函数中的
this默认指向window, 这样会打破数据的边界
可以通过严格模式,或者自动开启严格模式的Javascript Modules的方式