了解this的四种形式,看完这篇文章就足够了!!!

687 阅读2分钟

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

什么是this

this的值是在运行时绑定,函数的调用方式决定了this的值,简单来说this的值其实就是执行上下文(execution context)。

如何判断this的指向?

简单来讲就是谁调用它,this 就指向谁。

this的4种形式

1.通过简单的函数调用方式

当一个函数声明在全局作用域的时候,那么此时的上下文就是全局对象。在浏览器中就是window,而node环境中则是global;当然除了与环境有关还和是否是严格模式有关。

非严格模式浏览器环境

// 浏览器环境
function fun(){
    console.log(this) // window
}
fun()

image.png

非严格模式node 环境

// node 环境
function fun(){
    console.log(this) // global
}
fun()

image.png

严格模式浏览器环境

在浏览器环境下在函数外使用的话是指向window,但在函数里使用则指向undefined

// 浏览器环境
"use strict"
console.log(this) // window
function fun(){
    console.log(this) // undefined
}
fun()

image.png

当然把严格模式声明到函数里面也是如此undefined

// 浏览器环境
function fun(){
    "use strict"
    console.log(this) // undefined
}
fun()

image.png

严格模式node环境

函数外部使用则指向{},函数内部指向undefined

"use strict"
console.log(this) // {}
function fun(){
    console.log(this) // undefined
}
fun()

image.png

当然把严格模式声明到函数里面也是指向undefined

function fun(){
    "use strict"
    console.log(this) // undefined
}

image.png

那么嵌套函数呢?

嵌套函数

  • 非严格模式-浏览器环境
function fun1(){
    function fun2(){
        console.log(this) // window
    }
    fun2()
}
fun1()

image.png

  • 非严格模式-node环境
function fun1(){
    function fun2(){
        console.log(this) // global
    }
    fun2()
}
fun1()

image.png

  • 严格模式-浏览器环境
"use strict"
function fun1(){
    function fun2(){
        console.log(this) // undefined
    }
    fun2()
}
fun1()

image.png

  • 严格模式-node环境
"use strict"
function fun1(){
    function fun2(){
        console.log(this) // undefined
    }
    fun2()
}
fun1()

image.png

由此看来,我们可以看出与函数是否嵌套是无关了的。

2.通过对象属性方式调用函数

通过对象属性的方式调用函数的话,则会指向对象实例。

浏览器环境

let obj = {
    fun:function(){
        console.log(this) // obj
    }
}
obj.fun()

image.png

那么使用箭头函数会怎么样?

let obj = {
    fun:() => {
        console.log(this) // window
    }
}
obj.fun()

image.png

这是因为箭头函数本身没有this,是在全局中调用的所以指向window。

node环境

let obj = {
    fun:function(){
        console.log(this) // obj
    }
}
obj.fun()

image.png

箭头函数

"use strict"
let obj = {
    fun:() => {
        console.log(this) // {}
    }
}
obj.fun()

image.png

在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>

image.png

3.通过new调用函数

构造函数里的this,指向创建出来的实例。

es5写法

function fun(){
    console.log(this)
}
function Fun(){}
Fun.prototype.fun = fun
const f = new Fun()
f.fun() // Fun

image.png

es6写法

class Fun {
   constructor() {}
   fun(){
       console.log(this)
   }
}
const f = new Fun()
f.fun() // Fun

image.png

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})()

image.png