try块中的JavaScript作用域
假设我正在尝试执行这个JavaScript代码段。假设未声明的变量和方法在上面的其他地方声明,并且try块中的JavaScript作用域,javascript,scope,Javascript,Scope,假设我正在尝试执行这个JavaScript代码段。假设未声明的变量和方法在上面的其他地方声明,并且something和somethingElse的计算结果为布尔真 try { if(something) { var magicVar = -1; } if(somethingElse) { magicFunction(magicVar); } } catch(e) { doSomethingWithError(e); }
something
和somethingElse
的计算结果为布尔真
try {
if(something) {
var magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
我的问题是:
magicVar
的范围是什么?可以像我所做的那样将其传递到magicFunction
中吗?对于var
,变量从函数的开始到结束都存在,无论它们在何处声明,或者即使语句实际上已经到达。但是,在为它们分配另一个值之前,它们将是未定义的
因此,在您的例子中,如果something
为false,但somethingelse
为true,您将调用magicFunction
,其第一个参数为undefined
let
关键字是在Javascript 1.9中创建的,并且仅在Firefox中可用(截至今天,2012年5月3日,据我所知),它声明的变量具有您可能已经习惯的范围语义。- 在javascript中,仅函数创建一个新的上下文闭包李>
- 变量的每个定义实际上都是变量在其作用域顶部的声明,以及定义所在位置的赋值
- 功能范围
- 提升至其功能的顶部
- 同一作用域中相同名称的重新声明是无效的
吊装
您甚至可以执行以下操作:
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();
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
}
因此,foo
函数被转换为如下内容:
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();
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具有函数范围。这意味着
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“提升”(google it),您的变量声明代码被翻译为:
function yourFunction() {
var magicVar;
try {
if(something) {
magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
} //end of your function
“提升”将所有变量声明移动到函数顶部。因此,magicVar
在函数中的任何地方都可用,但是在您给它一个值之前它是未定义的
您的变量具有函数作用域。关于Javascript如何使用
var
处理此问题,有很多其他好的答案,但我想我应该解决让的情况
如果变量在try
块内定义为let
,则它将不在catch
(或finally
)块内的范围内。它需要在封闭块中定义
例如,在以下代码块中,控制台输出将为“外部”:
我同意可变吊装和功能吊装,我想强调两点
- Catch参数中定义的标识符为err/e(error),其作用域为Catch定义的块
- 功能先提升。
例如:
b(); // output : 3
var b = 2;
function b(){
return 3;
}
我累坏了!我爱你的和彼得·奥尔森的。投票表决:)@DarrenGreen.:)别难过。选择你认为最好的答案。(我不喜欢Stackoverflow的观点,即接受的答案会跳到最前面{我听到了吗?:)},没有意义的是,在这个问题上可能知识较少的人决定哪个答案是最好的。)如果是彼得的答案,我对它持冷静态度,我不会和你的答案竞争。你的备忘单链接被认为是过时的内容。喜欢那个页面上的大警告栏——你不会错过的!哈你给出的例子不太好,因为它是未定义的
,因为窗口。a
是未定义的
@gdoron我不确定我是否明白你的意思。如果您只是尝试单独运行alert(a)
,它将抛出一个错误,如a“未定义”
。问题是a
可能未定义,因为它在外部范围中未定义。如果您删除var x
您仍然会得到相同的结果,请看一下这个问题。@gdoron我仍然不明白您的意思。我的观点是,它将无错误运行,而将抛出一个错误。警报二然后抛出一个错误?(如果x没有在outerscope中定义)在我看来,这只是一个关于变量作用域的问题,而不是try块中的变量作用域。