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

dam*_*j07 4 javascript foreach scope this ecmascript-6

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

像这样......

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

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

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

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

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

//variant 3
for(var i =0 ;i.......){
   var temp = "tempvariable";
   //some code here
 }

 console.log(temp);
 //output : tempvariable
Run Code Online (Sandbox Code Playgroud)

variant2variant3代码片段有什么区别?

ade*_*neo 5

常规函数使用执行上下文来设置值this,这意味着在大多数情况下,值的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"
Run Code Online (Sandbox Code Playgroud)