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