如果在函数中定义变量 ,即使没有赋值,它也会变成局部变量
那么, testB()更好的编程?
var test = 'SNAP!'
function testA(boolean) {
if (boolean) var test = 'OK';
else var test = null;
alert(test);
}
function testB(boolean) {
if (boolean) var test = 'OK';
alert(test);
}
testA(true); // 'OK'
testB(true); // 'OK'
testA(false); // null
testB(false); // undefined, no error
在我的具体案例中,测试的全局值('SNAP!')既不是预期也不是必需的。
答案 0 :(得分:6)
您无法有条件地声明变量。
为什么?
变量实例化过程在实际执行代码之前发生,在执行函数时,这些变量已经绑定到本地范围,例如:
function foo () {
if (false) {
var test = 'foo'; // never executed
}
return test;
}
foo(); // undefined
当即将执行该函数时,形式参数的标识符,变量声明中的标识符以及函数体内函数声明的标识符将绑定到局部变量环境。
使用undefined
初始化变量。
此外,本地范围中的标识符 shadow 具有相同名称的其他标识符,在范围链中更高,例如:
var test = 'global';
function bar () {
alert(test); // undefined, not "global", the local variable already declared
var test = 'xxx';
}
bar();
如果test
变量未在任何地方声明,则会抛出ReferenceError
:
function foo () {
return test;
}
try {
foo(); // ReferenceError!!
} catch (e) {
alert(e);
}
这就是为什么例如,JSLint仅在函数顶部推荐one var
statement的原因之一,因为例如,第一个片段在执行时实际上类似于此:
function foo () {
var test; // var statement was "hoisted"
if (false) {
test = 'foo'; // never executed
}
return test;
}
foo(); // undefined
另一个原因是因为块没有引入新的词法范围,只有函数会这样做,因此在外观中使用var
语句可能会让您认为变量的生命周期仅限于该块,但事实并非如此。
嵌套函数声明将具有类似hoisting的行为,它们将在代码执行之前声明为,但它们也会在那一刻初始化:
function foo () {
return typeof bar;
// unreachable code:
function bar() {
//..
}
}
foo(); // "function"
答案 1 :(得分:4)
如果变量不需要由任何其他函数操作,请将变量保留在具有var foo;
的函数内。
否则,如果确实需要在多个范围内访问和阅读,请将其保留在外面。但要记住,当你把它放在外面时,它会变得全球化。也就是说,除非你在自动执行函数中包装所有,这是最好的方法:
(function() {
var president='bush';
function blah() {
president='reagan';
}
function meh() {
president= 'carter';
}
document.getElementById('reagan').onclick=blah;
document.getElementById('carter').onclick=meh;
})();
alert( president ) // undefined
上述内容非常适合由该范围内定义的函数访问的变量。由于我点击了2个元素来设置总统,因此在两个函数之外定义它是有意义的,因为它们设置了相同的变量。
因此,如果您没有处理更改完全相同变量的多个函数,请将它们保留在函数的本地。
答案 2 :(得分:2)
testB更好的编程吗?不,因为它给出了“未定义”的意外结果(至少,我对此感到惊讶)并且很难阅读。
通常,变量应限制在需要它们的范围内,因此如果函数外部不需要“test”变量,则应将其声明为local。为避免混淆,请在使用前声明变量:
function testC(boolean) {
var test;
if (boolean) {
test = "OK";
}
else {
test = null;
}
alert(test);
}
除非你真的想要更改“test”的全局范围版本,否则在这种情况下不要在函数内部使用var关键字。
如果你发现自己对局部变量和全局变量使用相同的名称,你可以考虑重命名其中一个。