我对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();
打印到控制台的内容是"全球"两次。这是因为当调用函数foo时,解释器首先检查foo的范围,看它是否有变量" x"然后检查全局范围,而不是bar或baz范围。变量" x"被抓住,而不是从调用函数foo的位置,而是从它创建的位置,因此在词法范围内。我是否正确,这是否有意义?
词法范围的另一个例子是闭包,对吧?因此,例如,内部函数可以访问外部函数的变量,无论因词法范围调用内部函数在哪里,都正确吗?
最后,我的最后一个例子是箭头功能。它们允许词汇范围界定"这个",对吗?所以,例如,
var obj = {
name: "Rob",
print() {
setTimeout(() => {
console.log(this.name)
}, 1000);
}
};
而不是"这个"如果它是一个标准的内联函数,则被绑定到全局对象,"这个"由于"这个"的词汇范围,因此必然会成为obj。带箭头功能。
我所说的一切都是正确的吗?还有,有人能给我一个明确的词汇范围定义吗?我应该知道JavaScript中的词法范围的其他示例吗?
感谢。
答案 0 :(得分:1)
您对范围如何适用于标准函数(包括闭包内的闭包)的理解是正确的,但对于箭头函数,这种说法是错误的:
“this”与obj绑定,因为带有箭头函数的“this”的词汇范围。
使用函数内的箭头函数this
与函数创建时函数外的this
相同。它不是绑定到示例中的obj
,而是绑定到已创建obj
的位置。
在以下情况下很有用:
this.values.filter( x => x < this.max );
在箭头函数this
内部与函数外部相同。使用常规函数,它可能是这样编写的:
this.values.filter( function ( x ) { return x < this.max }.bind( this ) );
或:
var self = this;
this.values.filter( function ( x ) { return x < self.max } );
答案 1 :(得分:1)
要了解词汇范围,您需要对范围有一个基本的了解。在javascript中,我们将范围分为三种类型
功能范围->在功能范围内定义的变量在功能范围内考虑。 var 关键字用于在功能范围内定义变量。
阻止范围->在if,switch condition,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();
结果
猫
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
`。 变量的范围由其在源代码中的位置定义。 为了解析变量,javascript从最内层的范围开始并向外搜索,直到找到所要查找的变量。 词法作用域很好,因为我们可以通过查看代码轻松地弄清楚变量的值;而在动态范围界定中,变量的含义可以在运行时通过增加难度来改变
答案 2 :(得分:0)
当您查看某个程序的某些源代码时,您正在查看其词法结构。当程序实际运行时,执行可以跳转并且事物的评估可以改变。这是所有开始有意义的部分。
您可能希望将其视为功能词汇范围和阻止词汇范围。对于其他人,你似乎已经掌握了它的想法。
答案 3 :(得分:-1)
&#34;全球&#34;打印两次是因为&#34; foo&#34;是关闭,已添加&#34; x&#34;全局范围的记忆,这就是我学习的方式,闭包是记住的功能