我正在阅读Douglas Crockford的书"Javascript: The Good Parts"。他正在讨论范围,并说JS没有块范围:
在许多现代语言中,建议声明变量 尽可能晚,在第一个使用点。结果证明是这样的 对Javascript的错误建议,因为它缺少块范围。所以相反,它 最好声明顶部函数中使用的所有变量 功能体。
但是,我想不出一个很好的例子,为什么这个陈述有意义,看到一些验证这个陈述的例子真的很好。
答案 0 :(得分:6)
在顶部声明变量有助于避免这样的情况:
function outer() {
var i = 50;
function inner() {
alert(i);
var i= 30;
}
inner();
}
outer();
很多人都希望警报显示50
,他们会惊讶地看到undefined
。这是因为i
变量是在inner
函数中声明的,但直到alert
之后才初始化。因此它具有完整的功能范围,即使它在初次使用后被声明。
答案 1 :(得分:3)
在函数顶部声明变量,作为记录在一个地方使用的所有变量的方法。
它还可以避免由于某人想象变量是实际上没有的块块而导致的混淆,如下所示:
var i=0;
if (true) {
var i=1;
}
// what is i? C programmer might imagine it's 0.
如果变量也在声明时被初始化,那么将声明置于顶部可以避免初始化时间的潜在问题:
console.log(foo);
var foo = 1;
在这种情况下,foo
被提升,因此它在console.log
时声明,但尚未初始化。所以这有点像
var foo;
console.log(foo); // no ReferenceError, but undefined
foo = 1;
答案 2 :(得分:0)
从我的观点来看,由于javascript没有块范围,因此在函数顶部声明所有变量会使您找到更容易使用的变量,因为您可以重用其他变量。
示例:
function test(){
var pages = [
'www.stackoverflow.com',
'www.google.com'
];
var users = [
'John',
'Bob'
];
for (var page = 0; page < pages.length; page++) {
console.log(pages[page]);
};
for (var user = 0; user < users.length; user++) {
console.log(users[user]);
};
}
可以更改为:
function test(){
var index, pages, users;
pages = [
'www.stackoverflow.com',
'www.google.com'
];
users = [
'John',
'Bob'
];
for (index = 0; index < pages.length; index++) {
console.log(pages[index]);
};
for (index = 0; index < users.length; index++) {
console.log(users[index]);
};
}
并从内存中保存一个变量空间。
在如此小的功能中,主要观点可能不明显,但想象一下整个项目有千行代码。这可能会使您的代码运行得更快。
答案 3 :(得分:0)
这并不总是一个好主意。这取决于你正在做什么。当他们说没有必要声明"top level"
变量时,他们的意思是,它并不重要。它在函数内部很重要。请考虑以下示例:
varOne = 1; varTwo = 2; varThree = 3; // undeclared
function lameFunc(){
var varOne = 'Something'; // does no affect varOne at the top level
return varOne;
}
同样:
var varOne = 1, varTwo = 2, varThree = 3; // declared
function lameFunc(){
var varOne = 'Something'; // does no affect varOne at the top level
return varOne;
}
当然,使用关键字var
更容易看到变量,并且由于"top level"
没有任何不利影响,建议使用。
请注意,当我更改lameFunc()
时,无论如何都会影响更高的杠杆var
。
function lameFunc(){
/* varOne is effected at the higher level whether or not `var` is declared
above as in `varOne = 1` or `var varOne = 1` */
varOne = 'Something';
return varOne;
}
此外,如果您在var someInputVal = document.getElementById('someInput').value;
之类的事件之外声明一个变量,那么假设您想要获取元素的值。您希望在var
中声明Element.onclick = function(){/* in here */}
,因为在您点击Element
之前输入可能已更改。在处理您的事件的函数之外声明var someInput = document.getElementById('someInput');
可能是可以的,如果元素没有成为undefined
那么您可以访问类似的内容:
var doc = document, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
var someInput = E('someInput'), someInputVal = someInput.value;
E('clickButton').onclick = function(){
console.log(someInputVal); // will not be what document.getElementById('someInput').value is if it was changed before clicking
var declared = someInput.value;
console.log(declared);
}