尝试块中的 JavaScript 范围
JavaScript scope in a try block
假设我正在尝试执行这个JavaScript代码片段。假设未声明的变量和方法是在上面的其他地方声明的,并且something
和somethingElse
计算结果为布尔值。
try {
if(something) {
var magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
我的问题是:magicVar
的范围是什么,是否可以像我一样将其传递给magicFunction
?
关于 Javascript 如何使用 var
处理这个问题还有很多其他很好的答案,但我想我会解决let
的情况......
如果变量在try
块内使用 let
定义,则它不会在catch
(或finally
)块内的范围内。 它需要在封闭块中定义。
例如,在以下代码块中,控制台输出将为"外部":
let xyz = "Outside";
try {
let xyz = "Inside";
throw new Error("Blah");
} catch (err) {
console.log(xyz);
}
Javascript 具有函数作用域。这意味着magicvar
从声明的函数的开头一直存在到该函数的末尾,即使该语句从未执行过。这称为可变吊装。函数声明也会发生同样的事情,这反过来称为函数提升。
如果变量是在全局范围内声明的,它将对所有内容可见。这就是为什么全局变量在Javascript中被认为是邪恶的部分原因。
如果 something
false,您的示例将undefined
传递到magicFunction
,因为magicVar
尚未分配给任何内容。
虽然这在技术上是有效的Javascript,但它通常被认为是糟糕的风格,并且不会像jsLint那样通过样式检查器。像这样极其不直观的Javascript将毫无错误地执行
alert(a); //alerts "undefined"
var a;
弹出测验:以下代码有什么作用?
(function() {
x = 2;
var x;
alert(x);
})();
alert(x);
- 在javascript中,只有函数创建一个新的上下文闭包。 变量
- 的每个定义实际上都是变量在其范围的顶部的声明,以及定义所在位置的赋值。
变量
- 函数作用域
- 提升到其功能的顶端
- 同一范围内同名的重新声明是无操作的
你可能想阅读MDN范围备忘单
由于hoisting
你甚至可以做这样的事情:
function bar() {
var x = "outer";
function foo() {
alert(x); // {undefined} Doesn't refer to the outerscope x
// Due the the var hoising next:
x = 'inner';
var x;
alert(x); // inner
}
foo();
}
bar();
bar();
演示
因此,foo
函数转换为如下所示的内容:
function foo() {
var x;
alert(x); // {undefined} Doesn't refer to the outerscope x
// Due the the var hoising next:
x = 'inner';
alert(x); // inner
}
我的问题是:magicVar的范围是什么,是否可以像我一样将其传递给magicFunction?
定义好的...,是的,代码是有效的,但是如果变量声明在顶部,那么它的可读性较差,仅此而已。
由于javascript的"提升"(MDN描述),你的变量声明代码被翻译为:
function yourFunction() {
var magicVar;
try {
if(something) {
magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
} //end of your function
"提升"将所有变量声明移动到函数的顶部。 因此,magicVar
函数中的任何地方都可用,但在您为其指定值之前,它是未定义的。
变量具有函数作用域。
对于var
,变量从函数的开头到函数的结尾都存在,无论它们在哪里声明,或者即使语句实际上曾经到达过。但是,它们将被undefined
,直到为它们分配另一个值。
因此,在您的情况下,如果something
是假的,但somethingelse
是真的,您将调用magicFunction
,其第一个参数是undefined
。
let
关键字是在 Javascript 1.9 中创建的,并且仅在 Firefox 中可用(截至今天,2012 年 5月 3 日,据我所知),它声明了具有您可能习惯的作用域语义的变量。
我同意可变吊装和功能提升,我想强调两个要点。
-
在 Catch 参数中定义的标识符是 err/e(error) ,范围为 Catch 定义的块。
-
功能先吊。例:
b(); // output : 3 var b = 2; function b(){ return 3; }
- 获取给定JavaScript范围内的解析函数
- 生成时间戳日期|Javascript范围内的空数据
- 注入函数中的 JavaScript 范围
- 可能存在Javascript范围问题
- JavaScript范围说明
- 如何获取整个 JavaScript 范围内上次单击的事件数据
- 下面的 JavaScript 范围是如何工作的
- 关于 JavaScript 范围的澄清
- JavaScript 范围和执行上下文
- Javascript 范围和此关键字的使用
- 变量和框架的 JavaScript 范围
- 使用此标识符的函数的 JavaScript 范围规则
- Javascript 范围:为什么 foo 返回未定义
- Javascript - 范围问题 - 有很好的Javascript答案
- JavaScript 范围和全局变量
- Javascript范围在角度SPA应用程序中不起作用
- KineticJS - 基本的JavaScript范围问题
- 我的JavaScript范围有什么问题
- 尝试块中的 JavaScript 范围
- JavaScript 范围/代码迭代不同步