JS是一段一段執行的(以<script>標簽來分割),執行每一段之前,都有一個“預編譯”,預編譯干的活是:聲明所有var變量(初始為undefined),解析定義式函數語句。
還有個關於 "window作用域下,a = 1和var a = 1" 的區別的也很經典:
a = 1相當於window.a = 1,是動態地為window添加一個成員;
var a = 1是在當前作用域(也就是window)下聲明一個a,這個聲明是在整個作用域內都有效的。
換句話說,其實區別就在於var a = 1比a = 1多了一個聲明的行為。
var a = 1是在當前作用域(也就是window)下聲明一個a,這個聲明是在整個作用域內都有效的。
換句話說,其實區別就在於var a = 1比a = 1多了一個聲明的行為。
再看幾個例子:
1.
alert(t);
alert('ok');
t = 2;
alert('ok');
t = 2;
t未聲明,執行報錯。
2.
alert(t);
alert('ok');
var t = 2;
alert('ok');
var t = 2;
彈出undefined和ok。預編譯的時候,聲明了變量t;執行到alert(t)這行代碼的時候,t尚未被賦值,所以彈出undefined。
3.
a();
function a() {}
alert('ok');
function a() {}
alert('ok');
彈出ok。預編譯的時候,解析了定義式函數語句function a() {},順利執行。
4.
a();
var a = function() {};
alert('ok');
var a = function() {};
alert('ok');
a不是函數,執行報錯。預編譯的時候,聲明了變量a = undefined;執行到a()時,a還等於undefined,不是函數,所以執行a()會報錯。
5.
a();
alert('first block');
</script>
<script type="text/javascript">
alert('second block');
</script>
6.
- 彈出second block。因為JS是一段一段執行的,第一段執行到a()的時候報錯,整個第一段都不會再執行,第二段正常執行。
firefox下的還有個小技巧:
如果上述例子中該報錯的沒有報錯,輸入about:config, 搜索strict, 看下javascript.options.strict, 如果是false的把他改為true。