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 中的词法范围的任何其他示例吗?
谢谢。
要理解词法作用域,您需要对作用域有基本的了解。在 javascript 中,我们将作用域分为三种类型
函数作用域-> 函数内部定义的变量被视为在函数作用域内。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 从最内部的范围开始向外搜索,直到找到它正在寻找的变量。词法作用域很好,因为我们可以通过查看代码轻松找出变量的值;而在动态作用域中,变量的含义可以在运行时改变,从而使其变得更加困难
您对范围如何适用于标准函数(包括闭包内的闭包)的理解是正确的,但对于箭头函数,此声明是错误的:
由于带有箭头函数的“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)