词汇范围的简要介绍是什么?
当前回答
作用域是可访问变量/绑定的上下文。词法范围是指封闭词法块的局部范围,而不是全局范围。
其他回答
让我们尝试最短的定义:
词法作用域定义了如何在嵌套函数中解析变量名:即使父函数已返回,内部函数也包含父函数的作用域。
这就是它的全部!
IBM将其定义为:
一个程序或段单元的一部分,其中有一个声明应用。例程中声明的标识符在例程和所有嵌套例程中。如果嵌套例程声明具有相同名称的项,外部项在嵌套例程。
示例1:
function x() {
/*
Variable 'a' is only available to function 'x' and function 'y'.
In other words the area defined by 'x' is the lexical scope of
variable 'a'
*/
var a = "I am a";
function y() {
console.log( a )
}
y();
}
// outputs 'I am a'
x();
示例2:
function x() {
var a = "I am a";
function y() {
/*
If a nested routine declares an item with the same name,
the outer item is not available in the nested routine.
*/
var a = 'I am inner a';
console.log( a )
}
y();
}
// outputs 'I am inner a'
x();
词汇范围是指从执行堆栈中的当前位置可见的标识符(例如,变量、函数等)的词汇。
- global execution context
- foo
- bar
- function1 execution context
- foo2
- bar2
- function2 execution context
- foo3
- bar3
foo和bar总是在可用标识符的词典中,因为它们是全局的。
当执行function1时,它可以访问foo2、bar2、foo和bar的词典。
当执行function2时,它可以访问foo3、bar3、foo2、bar2、foo和bar的词典。
全局和/或外部函数无法访问内部函数标识符的原因是,该函数的执行尚未发生,因此,其标识符均未分配给内存。此外,一旦内部上下文执行,它就会从执行堆栈中删除,这意味着它的所有标识符都已被垃圾收集,不再可用。
最后,这就是为什么嵌套的执行上下文总是可以访问它的祖先执行上下文,因此它可以访问更大的标识符词典。
See:
https://tylermcginnis.com/ultimate-guide-to-execution-contexts-hoisting-scopes-and-closures-in-javascript/https://developer.mozilla.org/en-US/docs/Glossary/Identifier
特别感谢@robr3rd帮助简化上述定义。
这是一个古老的问题,但这是我对它的看法。
词法(静态)范围是指源代码中变量的范围。
在JavaScript这样的语言中,函数可以被传递、附加和重新附加到其他对象,您可能会想到,这个范围将取决于当时调用该函数的人,但事实并非如此。以这种方式更改作用域将是动态作用域,而JavaScript不会这样做,除非可能使用此对象引用。
要说明这一点:
var a=“苹果”;函数doit(){var a=“ardvark”;返回函数(){警报(a);}}var test=doit();测试();
在示例中,变量a是全局定义的,但在doit()函数中隐藏。此函数返回另一个函数,如您所见,该函数依赖于自身范围之外的变量。
如果您运行这个,您会发现使用的值是aardwark,而不是apple,虽然它在test()函数的范围内,但不在原始函数的词法范围内。也就是说,使用的范围是源代码中显示的范围,而不是实际使用函数的范围。
这一事实可能会产生令人讨厌的后果。例如,您可能会决定更容易单独组织函数,然后在时间到来时使用它们,例如在事件处理程序中:
var a=“苹果”,b=“香蕉”;函数init(){var a=“ardvark”,b=“andicoot”;document.querySelector('button#a').onclick=函数(事件){警报(a);}document.querySelector('button#b').onclick=doB;}函数doB(事件){警报(b);}init();<button id=“a”>a</button><button id=“b”>b</button>
此代码示例分别执行其中一项。您可以看到,由于词法作用域,按钮A使用内部变量,而按钮B不使用。您可能最终嵌套的函数比您想要的更多。
顺便说一句,在这两个示例中,您还将注意到,即使包含函数函数已经运行,内部词汇范围内的变量仍然存在。这称为闭包,指的是嵌套函数对外部变量的访问,即使外部函数已经完成。JavaScript需要足够聪明,以确定这些变量是否不再需要,如果不需要,可以垃圾收集它们。
作用域是可访问变量/绑定的上下文。词法范围是指封闭词法块的局部范围,而不是全局范围。
推荐文章
- 如何使用Jest测试对象键和值是否相等?
- 将长模板文字行换行为多行,而无需在字符串中创建新行
- 如何在JavaScript中映射/减少/过滤一个集?
- Bower: ENOGIT Git未安装或不在PATH中
- 添加javascript选项选择
- 在Node.js中克隆对象
- 为什么在JavaScript的Date构造函数中month参数的范围从0到11 ?
- 使用JavaScript更改URL参数并指定默认值
- 在window.setTimeout()发生之前取消/终止
- 如何删除未定义和空值从一个对象使用lodash?
- 检测当用户滚动到底部的div与jQuery
- 在JavaScript中检查字符串包含另一个子字符串的最快方法?
- 检测视口方向,如果方向是纵向显示警告消息通知用户的指示
- ASP。NET MVC 3 Razor:在head标签中包含JavaScript文件
- 禁用从HTML页面中拖动图像