【JS错题总结】关于上下文

发布时间 2023-06-15 20:42:01作者: zjy4fun
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function func1() {
        console.log(1, this.value)
    }

    const myObject = {
        value: 'hello',

        func1: function(p1) {
            console.log(2, p1)
        },

        func2: function() {
            setTimeout(function() {
                this.func1(this.value) // 1 undefined
            }, 1)

            setTimeout(() => {
                this.func1(this.value) // 2 'hello'
            }, 10)

            setTimeout(() => {
                this.func1.apply(window, [this.value]) // 2 'hello'
            }, 100)

            setTimeout(function() {
                this.func1.apply(myObject) // 1 'hello'
            }, 100)
        }
    }

    myObject.func2()
</script>

</body>
</html>

第一个 setTimeout 中函数打印 1 undefined ,原因是 setTimeout 函数的回调是普通函数表达式

它没有绑定特定的上下文,因此在该回调函数内部,this 指向全局对象 window。由于全局对象 window 没有 value 属性,所以打印结果为 1 undefined

 

第二个 setTimeout 中函数打印 2 hello,原因是箭头函数继承了其外部作用域的 this 值,因此它使用了包含它的函数的上下文,即 myObject 对象。在这种情况下,this.value 的值为 hello,因此打印结果为 2  hello

 

第三个 setTimeout 中函数打印 2 hello,原因是使用了箭头函数后,调用的函数还是myObject.func1,传入的值还是 hello,只不过是将该函数和传入的值拿到最外层的上下文中执行

 

第四个 setTimeout 中函数打印 1 hello,原因是使用普通函数,没有绑定特定的上下文,此时的 this 指向的是最外层的上下文,调用的函数也是最外层的func1,所以会打印 1,但是通过 apply myObject,外层的 func1 函数中的 this.value 可以从 myObject 中拿到,所以会打印 hello