为什么“this”是超出其范围的变量?[复制]

Why is "this" the variable outside its scope? [duplicate]

提问人:jeromecho 提问时间:8/25/2021 更新时间:8/25/2021 访问量:49

问:

var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
  console.log(this); // <nav> element
  setTimeout(function () {
    console.log(this); // [object Window]
  }, 1000);
};

在上面的示例代码中,当变量 nav 在 toggleNav 的范围之外声明时,为什么第 3 行中的这个元素是元素?谢谢

JavaScript 作用域

评论

0赞 Hans Krohn 8/25/2021
这在JS中是一件有趣的事情。看看这篇文章 stackoverflow.com/questions/3127429/...
0赞 Sebastian Simon 8/25/2021
在没有上下文的情况下调用回调函数。从复制目标:使用箭头函数作为回调,或使用 ...function(){}.bind(this)
0赞 RobG 8/25/2021
@SebastianSimon - 所有函数都是在执行上下文中调用的,区别在于函数的设置方式取决于它的调用方式(以及使用箭头函数的词法)。;-)
0赞 Sebastian Simon 8/25/2021
@RobG我知道......“上下文”一词被过度使用。它可能应该是“隐式绑定的基本引用”左右。this
0赞 DJ Burb 8/25/2021
如果你想解决这个问题,你可以试试这个:var toggleNav = () => { console.log(this); // <nav> element setTimeout(function () { console.log(this); // [object Window] }, 1000); };

答:

1赞 parikshit parmar 8/25/2021 #1

即使在同一个函数中,作用域和此值也会不同。

发生了什么事?我们创建了一个新的范围,并且没有在事件处理程序中触发它,因此它获取了预期的 Windows 对象。如果我们希望这个值不受新创建的作用域的影响,我们可以采取一些措施。正如您之前可能已经看到的,我们使用它来创建对此和词法绑定的缓存引用 所以我们能做的就是。

var nav = document.querySelector('.nav');//<nav class="nav">

var toggleNav = function () {

var that = this;

console.log(that);//<nav> element

setTimeout(function () {

console.log(that);//<nav> element}, 1000);

};

nav.addEventListener('click', toggleNav, false); ```


评论

1赞 RobG 8/25/2021
该问题与范围无关。值由调用设置,或在箭头函数中按词法设置。问题是 setTimeout 没有设置 this 的回调,因此它们默认为全局对象(浏览器中的窗口)或严格模式下的 undefined。@sebastianSimpon 对使用 bind 的评论是一种(通常是最好的)解决方案。箭头函数和闭包是另一个。