简体   繁体   English

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

[英]Context and variable scope in ES6 loops and forEach

In ES5, if I have to refer to the this context of parent function in child function I have to store it in a variable and access it inside child function using that variable. 在ES5中,如果我必须在子函数中引用父函数的this上下文,我必须将它存储在变量中并使用该变量在子函数内访问它。

Something like this ... 像这样......

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

ECMAScript has arrow functions so I can avoid this: ECMAScript有箭头功能,所以我可以避免这种情况:

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

The question that I have is: If I was to declare a variable temp inside my forEach function above will this pollute my global scope? 我的问题是:如果我要在上面的forEach函数中声明一个变量temp ,那么这会污染我的全局范围吗? If so will this have performance issues and variable conflicts? 如果是这样,这会有性能问题和可变冲突吗?

Something similar happens in for loop .... 在for循环中发生了类似的事情....

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

 console.log(temp);
 //output : tempvariable

What is the difference between variant2 and variant3 code snippets? variant2variant3代码片段有什么区别?

Regular functions use execution context to set the value of this , meaning that in in most cases, the value of this is determined by how a function is called, ie the value of this is set according to the environment in which the function is executed. 常规函数使用执行上下文来设置this的值, this意味着在大多数情况下, this的值由函数的调用方式决定,即this的值是根据函数执行的环境设置的。

Arrow functions do not have their own this value, instead they use lexical scoping, meaning the value of this inside an arrow function is always inherited from the enclosing scope, ie it is set to the this value of the enclosing execution context. 箭头函数没有自己的this值,而不是他们使用的词汇范围,这意味着价值this一个箭头函数内部总是从封闭的范围继承,也就是说,它被设置为this封闭的执行上下文的价值。

This is explained in the documentation as well 这也在文档中进行了解释

Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). 在箭头函数之前,每个新函数都定义了它自己的this值(在构造函数的情况下是一个新对象,在严格模式函数调用中是未定义的,如果函数被称为“对象方法”则是上下文对象,等等)。 This proved to be annoying with an object-oriented style of programming. 事实证明,这是一种面向对象的编程风格。
.... ....
Arrow functions capture the this value of the enclosing context 箭头函数捕获封闭上下文的此值

The third example posted is just a regular for loop, and has very little in common with functions, and can't really be compared to the two first code examples. 发布的第三个示例只是一个常规for循环,与函数几乎没有共同点,并且无法与两个第一个代码示例进行比较。
for loops work the same in ES2015 as they always have, there generally is no special scope in for loops for variables, as variables (defined with var ) are function scoped. for循环的工作方式相同的ES2015,因为他们总是有,一般是没有什么特别的范围for变量循环,作为变量(与定义var是函数作用域。

However, ES2015 does introduce variables that can are block scoped as wel, and as a for loop is in fact a block ( for (what) {block} ) , those variables can be used, and they are defined with either the let keyword, or the const keyword for a constant (that can not be changed) . 但是,ES2015确实引入了可以作为块作用域的变量,并且因为for循环实际上是一个块for (what) {block} ,可以使用这些变量,并且使用let关键字定义它们,或const关键字(不能更改)

For those that prefer code 对于那些喜欢代码的人

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM