ES6 循环和 forEach 中的上下文和变量范围

Context and variable scope in ES6 loops and forEach

本文关键字:上下文 变量 范围 循环 forEach ES6      更新时间:2023-09-26

在 ES5 中,如果我必须在子函数中引用父函数的this上下文,我必须将其存储在变量中,并使用该变量在子函数中访问它。

像这样的东西...

//  variant 1
var self = this;
this.nums.forEach(function (v) {
if (v % 5 === 0)
   self.fives.push(v);
});

ECMAScript 有箭头函数,所以我可以避免这种情况:

// variant 2
this.nums.forEach((v) => {
 if (v % 5 === 0)
   this.fives.push(v)
})

我的问题是:如果我在上面的forEach函数中声明一个变量temp,这会污染我的全局范围吗?如果是这样,这会产生性能问题和变量冲突吗?

类似的事情发生在 for 循环中....

//variant 3
for(var i =0 ;i.......){
   var temp = "tempvariable";
   //some code here
 }
 console.log(temp);
 //output : tempvariable
变体

2变体 3 代码片段有什么区别?

常规函数使用执行上下文来设置this的值,这意味着在大多数情况下,this的值由函数的调用方式决定,即this的值是根据执行函数的环境设置的。

箭头函数没有自己的this值,而是使用词法作用域,这意味着箭头函数内的this值始终继承自封闭范围,即它设置为封闭执行上下文的this值。

这在文档中也有解释

在箭头函数之前,每个新函数都定义了自己的this值 (构造函数中的新对象,在严格模式下未定义 函数调用,如果函数作为 "对象方法"等)。事实证明,这很烦人 面向对象的编程风格。
....
箭头函数捕获封闭上下文的此值

发布的第三个示例只是一个常规的for循环,与函数几乎没有共同之处,无法与前两个代码示例进行比较。
for循环在 ES2015 中的工作方式与往常相同,但在变量for循环中通常没有特殊作用域,因为变量(用 var 定义)是函数作用域。

但是,ES2015确实引入了可以块范围的变量,并且由于for循环实际上是一个块for (what) {block}),可以使用这些变量,并且它们使用let关键字或常量(无法更改)const关键字定义。

对于那些喜欢代码的人

var o = {
    nums  : [1,2,3,4],
    fn    : function() {
        var self = this;
        this.nums.forEach(function(v) {
            // "this" in this context would be the window,
            // but "self" would be the object "o", hence the common use of this hack
        });
        this.nums.forEach((v) => {
            // "this" in this context, would be the object "o"
            // that happens because the "this-value" in the fn() function,
            // ... is the parent object
            // and the arrow function inherits that this-value
        });
        for (var i=0; i<this.nums.length; i++) {
            // "this" in this context is what it has always been,
            // a for-loop has the same this-value as the surrounding scope
        }
    }
}
o.fn(); // called from global context "window"