「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」
什么是this
this的值是在运行时绑定,函数的调用方式决定了this的值,简单来说this的值其实就是执行上下文(execution context)。
如何判断this的指向?
简单来讲就是谁调用它,this 就指向谁。
this的4种形式
1.通过简单的函数调用方式
当一个函数声明在全局作用域的时候,那么此时的上下文就是全局对象。在浏览器中就是window,而node环境中则是global;当然除了与环境有关还和是否是严格模式有关。
非严格模式浏览器环境
// 浏览器环境
function fun(){
console.log(this) // window
}
fun()
非严格模式node 环境
// node 环境
function fun(){
console.log(this) // global
}
fun()
严格模式浏览器环境
在浏览器环境下在函数外使用的话是指向window,但在函数里使用则指向undefined
// 浏览器环境
"use strict"
console.log(this) // window
function fun(){
console.log(this) // undefined
}
fun()
当然把严格模式声明到函数里面也是如此undefined
// 浏览器环境
function fun(){
"use strict"
console.log(this) // undefined
}
fun()
严格模式node环境
函数外部使用则指向{},函数内部指向undefined
"use strict"
console.log(this) // {}
function fun(){
console.log(this) // undefined
}
fun()
当然把严格模式声明到函数里面也是指向undefined
function fun(){
"use strict"
console.log(this) // undefined
}
那么嵌套函数呢?
嵌套函数
- 非严格模式-浏览器环境
function fun1(){
function fun2(){
console.log(this) // window
}
fun2()
}
fun1()
- 非严格模式-node环境
function fun1(){
function fun2(){
console.log(this) // global
}
fun2()
}
fun1()
- 严格模式-浏览器环境
"use strict"
function fun1(){
function fun2(){
console.log(this) // undefined
}
fun2()
}
fun1()
- 严格模式-node环境
"use strict"
function fun1(){
function fun2(){
console.log(this) // undefined
}
fun2()
}
fun1()
由此看来,我们可以看出与函数是否嵌套是无关了的。
2.通过对象属性方式调用函数
通过对象属性的方式调用函数的话,则会指向对象实例。
浏览器环境
let obj = {
fun:function(){
console.log(this) // obj
}
}
obj.fun()
那么使用箭头函数会怎么样?
let obj = {
fun:() => {
console.log(this) // window
}
}
obj.fun()
这是因为箭头函数本身没有this,是在全局中调用的所以指向window。
node环境
let obj = {
fun:function(){
console.log(this) // obj
}
}
obj.fun()
箭头函数
"use strict"
let obj = {
fun:() => {
console.log(this) // {}
}
}
obj.fun()
在node环境下通过对象属性的方式调用函数则会指向{}。
DOM操作
<html>
<button id="a">A</button>
<button id="b">B</button>
<script>
function fn() {
console.log(this)
}
document.getElementById('#a').addEventListener('click',fn)
document.getElementById('#b').addEventListener('click',fn)
</script>
</html>
3.通过new调用函数
构造函数里的this,指向创建出来的实例。
es5写法
function fun(){
console.log(this)
}
function Fun(){}
Fun.prototype.fun = fun
const f = new Fun()
f.fun() // Fun
es6写法
class Fun {
constructor() {}
fun(){
console.log(this)
}
}
const f = new Fun()
f.fun() // Fun
4.通过call、apply、bind方法
通过call、apply、bind方法可以改变this指向
function fun() {
console.log(this)
}
fun()
fun.apply({id:1})
fun.call({id:2})
fun.bind({id:3})()