About Argument & Function Are Hoisted in JavaScript
在很多语言如果是使用未定义的变量,通常会造成编译错误或者运行时抛出异常。 而对于JavaScript,则不会出现问题。下面的代码你拿去运行完全没有问题:
在很多语言如果是使用未定义的变量,通常会造成编译错误或者运行时抛出异常。
而对于JavaScript,则不会出现问题。下面的代码你拿去运行完全没有问题:
function test() {
alert(name);
var name = 'foo';
alert(name);
}
test();或者:
test();
function test() {
alert('foo');
}造成这些原因是都是JavaScript解析器的错,解析器会对当前作用域内的变量和函数的声明提前,
对于变量它的赋值操作则保留在原来的位置,而对于函数后面会单独说。
变量被提前
比如前面提到的第一个例子,实际在test函数内部是解释期间是这样的:
function test() {
var name;
alert(name);
name = 'foo';
alert(name);
}再来看一个例子,各位想想下面的输出会是什么?
var name = 'foo';
(function () {
alert(name);
name = 'bar';
alert(name);
})();在这里可以验证,jsfiddle
以及下面的代码会输出什么?
var name = 'foo';
(function () {
alert(name);
var name = 'bar';
alert(name);
})();同样也可以在这里验证,jsfiddle
提示:只对当前作用域中声明的变量提前。
函数声明被提前
在一开始的例子中,test函数会被正确执行,所以是函数的整个定义都被提前了。
再来看下面的一个例子:
foo();
bar();
function foo() {
alert('foo');
}
var bar = function() {
alert('bar');
};输出将会是:
alert foo
undefined is not a function验证地址,jsfiddle看错误的时候,记得developer tools.
会出现这两个不同结果是因为,函数被提前分两种:
- 函数声明被提前
- 函数赋值给变量被提前
所以,实际情况是:
function foo() {
alert('foo');
}
var bar;
foo();
bar();
bar = function () {
alert('bar');
};最后,为了避免被语言所坑,大家最好都是先声明在调用吧,能减少不必要的Debug时间。