JavaScript 中的词法作用域

E. *_*ers 7 javascript scope global lexical

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

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

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

var x = "global";

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

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

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


bar();
baz();
Run Code Online (Sandbox Code Playgroud)

打印到控制台的内容是“全局”两次。这是因为当函数 foo 被调用时,解释器首先检查 foo 的作用域,看它是否有变量“x”,然后检查全局作用域,而不是 bar 或 baz 作用域。变量“x”不是从函数 foo 被调用的地方获取的,而是从它被创建的地方获取的,因此是词法范围的。我是对的,这有意义吗?

词法作用域的另一个例子是闭包,对吧?例如,内部函数可以访问外部函数的变量,无论内部函数在哪里调用,因为词法作用域,对吗?

最后,我的最后一个例子是箭头函数。它们允许“this”的词汇范围,对吗?所以,例如,

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

如果“this”是一个标准的内联函数,那么它不是绑定到全局对象,而是绑定到 obj 因为“this”的词法范围是箭头函数。

我说的都是对的吗?另外,有人能给我一个明确的词法范围定义吗?我应该了解 JavaScript 中的词法范围的任何其他示例吗?

谢谢。

Ujj*_*pal 5

要理解词法作用域,您需要对作用域有基本的了解。在 javascript 中,我们将作用域分为三种类型

  1. 功能范围
  2. 块范围
  3. 词汇范围

函数作用域-> 函数内部定义的变量被视为在函数作用域内。var关键字用于在函数作用域内定义变量。

块作用域-> 在 if、switch 条件、for 和 while 循环内的区域中定义的变量。每当你看到“{}”大括号时,它就是一个块。在 Es6 中,const 和 let关键字允许开发人员在块作用域中声明变量。这意味着这些变量仅存在于相应的块中。

   function animal(){
    if(true){
        var animal1 = "cat";
        const animal2 = "dog";
        let animal3 = "rat";
    }
    console.log(animal1);
    console,log(animal2); //animal2 is not defiend
    console,log(animal3); //animal3 is not defiend
}
animal();
Run Code Online (Sandbox Code Playgroud)

结果

Animal2 未定义

Animal3 未定义

词法作用域-> 在第一行中我想说“子作用域可以访问父作用域中的变量”`

var outerFunction = function()
{
    if(true){
        var x = 5;
        const y = 10;
    }

    var innerFunction = function(){
        if(true){
            alert(x);
            //alert(y);   //y is not defiend on line 13

        }
    }
    innerFunction();
}
 outerFunction();
 //console.log(x); // x is not defiend on line 20
Run Code Online (Sandbox Code Playgroud)

`。变量的范围由它们在源代码中的位置定义。为了解析变量,javascript 从最内部的范围开始向外搜索,直到找到它正在寻找的变量。词法作用域很好,因为我们可以通过查看代码轻松找出变量的值;而在动态作用域中,变量的含义可以在运行时改变,从而使其变得更加困难


Pau*_*aul 2

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

由于带有箭头函数的“this”的词法作用域,“this”绑定到 obj。

函数内的箭头函数与创建函数时函数外的内容this相同。this在您的示例中,它并未绑定到obj,而是绑定到已经绑定到obj正在创建的位置的任何内容。

它在以下情况下很有用:

this.values.filter( x => x < this.max );
Run Code Online (Sandbox Code Playgroud)

箭头函数内部this与函数外部相同。对于常规函数,它可能会写成这样:

this.values.filter( function ( x ) { return x < this.max }.bind( this ) );
Run Code Online (Sandbox Code Playgroud)

或者:

var self = this;
this.values.filter( function ( x ) { return x < self.max } );
Run Code Online (Sandbox Code Playgroud)