this的指向
在非严格模式下,总是指向一个对象,在严格模式下可以是任意值,开启严格模式可以使用如下两种方式:
- 在整个脚本顶部开启
- 在函数顶部开启
// 为整个脚本开启严格模式
'use strict'
function func() {
// 为函数开启严格模式
'use strict'
}
然后就可以根据不同的模式来确认this指向啦,
全局执行环境
指向全局对象(非严格模式、严格模式)在浏览器环境下,全局对象是Window
//1.全局执行环境
//非严格模式: 不做任何设置,直接写就是非严格模式
console.log(this) // window
//严格模式: 代码顶部加上 'use strict' 即可
'use strict' // 为整个脚本开启严格模式
console.log(this) // window
函数内部
取决于函数被调用的方式
直接调用的this值
- 非严格模式:全局对象(window)
- 严格模式:undefined
// 2.函数内部
// 2.1 直接调用-非严格模式
function func() {
console.log(this) // 全局对象window
}
func()
// 2.1 直接调用-严格模式
function func() {
'use strict'
console.log(this) // undefined
}
func()
对象方法调用
this指向: 调用者(无论是否开启严格模式都是)
// 2.2 对象方法调用
const food = {
name: '猪脚饭',
eat() {
console.log('吧唧吧唧')
console.log(this)//调用者 food
}
}
food.eat()
箭头函数
箭头函数的this指向与上级作用域的this指向相同
构造函数
构造函数中的this指向实例对象
当你使用new关键字调用一个函数时,JavaScript引擎会执行以下步骤:
- 创建一个新的空对象:这个新对象会被作为构造函数的结果返回。
- 将新对象的原型(proto)链接到构造函数的prototype属性。
3. 将构造函数内部的this绑定到这个新创建的对象。 - 执行构造函数中的代码,对新对象进行初始化。
- 返回新对象(除非构造函数显式返回另一个对象,在这种情况下返回该对象)。
例如:
function test() {
console.log(this); // 这里的this指向通过new创建的新对象
function test2() {
console.log(this); // 这里的this指向全局对象(非严格模式下为window),严格模式下为undefined
}
test2();
}
// 使用new关键字调用test
const obj = new test();
test中的this
- 当使用new调用test时,test函数内部的this指向由new创建的新对象obj。
test2中的this
- test2是一个在test函数内部定义并直接调用的函数。即使test是通过new调用的,test2仍然是作为一个普通函数被调用的,而不是作为对象的方法或构造函数调用。
- 因此,test2中的this指向全局对象(如浏览器中的window),在严格模式下为undefined。
总结
如何确认this指向:
- 全局执行环境中,指向全局对象(非严格模式、严格模式)
- 如何开启严格模式:
// 为整个脚本开启严格模式
'use strict'
function func() {
// 为函数开启严格模式
'use strict'
}
- 函数内部,取决于函数被调用的方式
- 直接调用的this值:
- 非严格模式:全局对象(window)
- 严格模式:undefined
- 对象方法调用时的this值为调用者
- 箭头函数:与上一层作用域的this指向相同
- 构造函数:this指向实例对象
- 直接调用的this值:
改变this指向的方法
call
- 参数1:this
- 参数2-n:传递给函数的参数
//func.call(thisArg,参数1,参数2...)
// call参数
// 参数1 this值
// 参数2-参数n 挨个传入函数的参数
funcA.call(obj, 1, 2)
apply
以数组作为参数
- 参数1:this
- 参数2:以数组的形式,传递给函数的参数
//func.apply(thisArg,[参数1,参数2...])
// apply参数
// 参数1 this值
// 参数2 以数组的形式传入函数的参数
funcA.apply(obj, [3, 4])
bind
返回一个绑定了this的新函数
const bindFunc = func.bind(thisArg,绑定参数1,绑定参数2)
// bind参数
// 参数1 this值
// 参数2-参数n 绑定的参数
const bindFuncB = funcB.bind(person, 123)//绑定的参数1是123
bindFuncB(666)//由于参数1已经绑定为123,所以666是绑定参数2
总结
如何改变this指向,有三个改变this指向的方法,分别是:
- 调用函数时并传入具体的this
- call:从第二个参数开始挨个传递参数
- apply:在第二个参数以数组的形式传递参数
- 创建函数时绑定this?
- bind:返回一个绑定了this以及参数(可选)的新函数
以上列举了较为常见会被问到的this指向,还有更多详情查看官方MDN文档