gpt4 book ai didi

javascript - 使用箭头函数(Lexical this)时包围词法上下文的意义

转载 作者:行者123 更新时间:2023-12-05 02:05:26 24 4
gpt4 key购买 nike

我对 javascript 中的 this 有疑问。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

当我读这篇文章时,它说

In arrow functions, this retains the value of the enclosing lexical context's this. In global code, it will be set to the global object

但是比如下面的代码

const person = {
hobby: "loafing around",
sayHobby: function() {
setTimeout(() => {
console.log(`My hobby is ${this.hobby}`);
}, 100);
}
};

person.sayHobby()

在这个例子中,setTimeout 中的箭头函数回调被包含在 setTimeout 函数中。所以我认为 this 它应该是 global(window) 因为 setTimeout 是在 gloabal 对象中定义的。

我知道我的想法是错误的,但不知道如何理解enclosing lexical context的意思。你能帮我理解这个吗?如何找到词汇上下文?

最佳答案

在全局范围内 this 指向全局对象(在浏览器中它将是 window)。现在,当您调用 person.sayHobby() 时,sayHobby 不是箭头函数。所以这个调用创建了一个新的词法上下文,其中 this 指向 . 左边的任何内容,在 person.sayHobby() 中就是那个人对象。

接下来调用 setTimeout,它等同于 window.setTimeoutsetTimeout 调用将具有词法范围,其中 this 计算为窗口。但我们看不到这一点,因为 setTimeout 是一种内部浏览器方法。您看不到它的代码。

当您调用 setTimeout 时,您传递了一个函数参数。该参数包括调用者的词汇上下文。然后 setTimeout 调用你的箭头函数,它用传入的词法上下文调用它。

// global context
// this evaluates to window. This should output true
console.log('this here evaluates to window: ' + (window === this));
const person = {
hobby: "loafing around",
sayHobby: function() {
// This is a non arrow function. It creates a new lexical context
// This should also print true
console.log('this evaluates to the person object used for the call: ' + (this.hobby === 'loafing around'));
// setTimeout is called without this
// Any call without this. preceding it assumes that the function is in global object.
// So this is the same as window.setTimeout
setTimeout(() => {
// This is an arrow function. No new scope is created.
// This should print true
console.log('this evaluates to the person object used for the sayHobby call: ' + (this.hobby === 'loafing around'));
console.log(`My hobby is ${this.hobby}`);
}, 100);
}
};

// Calling person.sayHobby will make this evaluate to person inside the sayHobby() call
person.sayHobby();

现在让我们更改代码并在 globalScope 中定义一个全局函数

// 
function myGlobalFunction(callback) {
console.log('inside myGlobalFunction this evaluates to window: ' + (window === this));
callback();
}
// global context
// this evaluates to window. This should output true
console.log('this here evaluates to window: ' + (window === this));
const person = {
hobby: "loafing around",
sayHobby: function() {
// This is a non arrow function. It creates a new lexical context
// This should also print true
console.log('this evaluates to the person object used for the call: ' + (this.hobby === 'loafing around'));
// setTimeout is called without this
// Any call without this. preceding it assumes that the function is in global object.
// So this is the same as window.setTimeout
myGlobalFunction(() => {
// This is an arrow function. No new scope is created.
// This should print true
console.log('this evaluates to the person object used for the sayHobby call: ' + (this.hobby === 'loafing around'));
console.log(`My hobby is ${this.hobby}`);
}, 100);
}
};

// Calling person.sayHobby will make this evaluate to person inside the sayHobby() call
person.sayHobby();

这基本上是一样的。在 myGlobalFunction 内部,全局上下文有 this 指向 window。但是 callback 参数包括调用者的上下文。然后 callback() 以 person 作为上下文执行。

关于javascript - 使用箭头函数(Lexical this)时包围词法上下文的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63541194/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com