JavaScript中的词法范围 [英] Lexical Scope in JavaScript

查看:98
本文介绍了JavaScript中的词法范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对JavaScript的确切范围如何工作有点困惑,主要是词法范围。我知道全局范围内的变量可以在任何地方访问,而在JavaScript中创建新范围的唯一方法是通过创建函数(或在ES6中使用let)。但是,我真的不明白词汇范围/意味着什么。我已经浏览了整个互联网,无法找到明确的解释。

I am slightly confused as to how exactly scope works in JavaScript, mainly lexical scope. I understand that variables in global scope are accessible anywhere, and the only way to create a new scope in JavaScript is through the creation of functions (or with let in ES6). However, I do not really understand what lexical scope is/means. I have looked all over the internet and could not find a clear explanation.

我觉得我有点开始理解它,但是让我跟你确认一下JavaScript向导,以确保我是正确的。

I feel like I am kind of starting to understand it, but just let me confirm with you JavaScript wizards out there to make sure that I am correct.

因此,根据我的理解,词法范围意味着静态范围,因此,例如,函数的范围不是由调用它的位置创建的,而是由函数本身的创建位置创建的。以下代码演示了这一概念:

So, from my understanding, lexical scope means statically scoped, so for example, a function's scope is not created by where it is called but by where the function itself is created. The following code below demonstrates this concept:

var x = "global";

function foo() {
   console.log(x);
}

function bar() {
   var x = "bar";
   foo();
}

function baz() {
   var x = "baz";
   foo();
}


bar();
baz();

打印到控制台的内容是全局两次。这是因为当调用函数foo时,解释器首先检查foo的范围以查看它是否具有变量x然后检查全局范围,而不是bar或baz范围。变量x被抓取,而不是从调用函数foo的位置,而是从它创建的位置,因此在词法范围内。我是否正确,这是否有意义?

What is printed to the console is "global" twice. This is because when the function foo is invoked, the interpreter first checks foo's scope to see if it has a variable "x" then checks the global scope, not bar or baz scope. The variable "x" is grabbed, not from where the function foo is called, but from where it is created, hence lexically scoped. Am I correct, and is this making sense?

词汇范围的另一个例子是闭包,对吧?那么例如,内部函数可以访问外部函数的变量,无论因为词法范围调用内部函数在哪里,都正确吗?

Another example of lexical scope would be closures, right? So for example, the inner function has access to the outer function's variables, no matter where the inner function is called because of lexical scope, correct?

最后,我的最后一个例子将是箭头功能。它们允许词汇范围这个,对吧?所以,例如,

Finally, my last example would be arrow functions. They allow for the lexical scoping of "this", right? So, for example,

   var obj = {
       name: "Rob",
       print() {
       setTimeout(() => {
         console.log(this.name)
       }, 1000);
     }
   };

如果它是标准的内联函数,则不是this绑定到全局对象,这个由于带有箭头功能的this的词汇范围,因此必须使用obj。

Rather than "this" being bound to the global object if it were a standard inline function, "this" is bound to obj because of the lexical scoping of "this" with arrow functions.

我所说的一切都是正确的吗?还有,有人能给我一个明确的词汇范围定义吗?我应该知道JavaScript中的词法范围的其他示例吗?

Is everything I have said correct? Also, can someone just give me a clear-cut definition of lexical scope? Are there any other examples of lexical scope in JavaScript that I should know about?

谢谢。

推荐答案

您对范围如何适用于标准的理解函数(包括闭包内的闭包)是正确的,但是对于箭头函数,这个语句是错误的:

Your understanding of how scope works for standard functions (including closures inside closures) is correct, but for arrow functions this statement is wrong:


this绑定到obj因为带箭头函数的this的词汇范围。

"this" is bound to obj because of the lexical scoping of "this" with arrow functions.

使用箭头函数在函数内部与相同,这个在创建时不在函数之外。在你的例子中它没有绑定到 obj ,而是绑定到 obj 所在的位置已创建。

With an arrow function this within the function is the same as whatever this was outside the function when it was created. It is not bound to obj in your example, but instead to whatever it was already bound to where that obj is being created.

在以下情况下非常有用:

It is useful in a situation such as:

this.values.filter( x => x < this.max );

在箭头函数里面这个是一样的因为它在功能之外。使用常规函数它可能是这样写的:

Inside that arrow function this is the same as it was outside the function. With a regular function it might have been written like this:

this.values.filter( function ( x ) { return x < this.max }.bind( this ) );

或:

var self = this;
this.values.filter( function ( x ) { return x < self.max } );

这篇关于JavaScript中的词法范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆