说我正在尝试执行此JavaScript代码段。假设未声明的变量和方法在上面的其他地方声明,并且something
和somethingElse
计算为boolean-true。
try {
if(something) {
var magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
我的问题是:magicVar
的范围是什么,是否可以像我一样将其传递给magicFunction
?
答案 0 :(得分:30)
关于Javascript如何使用var
处理此问题的许多其他好答案,但我认为我会解决let
情况......
如果在let
块中使用try
定义变量,则它不在catch
(或finally
)块内的范围内。它需要在封闭块中定义。
例如,在以下代码块中,控制台输出将为“Outside”:
let xyz = "Outside";
try {
let xyz = "Inside";
throw new Error("Blah");
} catch (err) {
console.log(xyz);
}
答案 1 :(得分:21)
Javascript具有功能范围。这意味着magicvar
将从它声明的函数的开头一直存在到该函数的结尾,即使该语句没有执行。这称为变量提升。函数声明也会发生同样的事情,而声明又称为函数提升。
如果变量是在全局范围内声明的,那么所有内容都可以看到它。这是全局变量在Javascript中被认为是邪恶的部分原因。
如果undefined
为false,您的示例会将magicFunction
传递给something
,因为magicVar
尚未分配给任何内容。
虽然这是技术上有效的Javascript,但它通常被认为是不好的风格,并且不会传递像jsLint这样的样式检查器。非常不直观的Javascript会执行而不会出现任何错误
alert(a); //alerts "undefined"
var a;
POP QUIZ :以下代码有什么作用?
(function() {
x = 2;
var x;
alert(x);
})();
alert(x);
答案 2 :(得分:5)
<强> VAR 强>
您可能需要阅读MDN scope cheat sheet
由于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吗?
定义好的 ...,是的,代码是有效的,但如果变量声明位于顶部,那么它的可读性就会降低,这就是全部。
答案 3 :(得分:3)
由于javascript“hoisting”(google it),您的变量声明代码会被翻译为:
function yourFunction() {
var magicVar;
try {
if(something) {
magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
} //end of your function
“Hoisting”将所有变量声明移动到函数的顶部。因此magicVar
在函数的任何地方都可用,但在给它一个值之前它是未定义的。
您的变量具有功能范围。
答案 4 :(得分:1)
对于var
,变量从函数的开头到它的结尾都存在,无论它们在何处被声明,或者即使实际上已经到达了该语句。但是,它们将undefined
,直到它们被赋予另一个值。
因此,在您的情况下,如果something
为false但somethingelse
为真,您将调用magicFunction
,其第一个参数为undefined
。
{J} 1.9中创建的let
关键字(截至今天,5月3日 rd 2012,据我所知)仅在Firefox中,使用作用域声明变量您可能习惯的语义。
答案 5 :(得分:0)
我同意变量提升和功能提升,我想强调两个导入点。
Catch参数中定义的标识符即err / e(错误),其范围限定为Catch defined block。
功能首次提升。 例如:
await Navigation.PopAsync();