一、javascript的解析順序 我們大家所理解的代碼的執行順序都是從上到下的,但是實際上確不是這樣的。我們看一下下麵的代碼。 如果執行順序是從上到下的,在上面彈出一個a,瀏覽器會認為從上到下執行的,那麼當它alert(a)的時候,他就會發現沒有這個東西,那麼他就會報錯,但是實際上他彈出來的結果是 ...
一、javascript的解析順序
我們大家所理解的代碼的執行順序都是從上到下的,但是實際上確不是這樣的。我們看一下下麵的代碼。
1 alert(a); 2 var a = 1;
如果執行順序是從上到下的,在上面彈出一個a,瀏覽器會認為從上到下執行的,那麼當它alert(a)的時候,他就會發現沒有這個東西,那麼他就會報錯,但是實際上他彈出來的結果是undefined。返回值是undefined說明a沒有被定義也就是沒有賦值。下麵我來講解一下javascript的解析順序。
1.ES5中有聲明意義的關鍵字
var 會存在變數提升
function 也有聲明變數的的作用。
2.解析順序
1.找聲明 var、function 聲明:只是聲明變數,而不包括賦值。
2. 執行
註意:以上兩步 都遵循從上至下,執行的時候遇到等號,先看等號的右邊。
註意:當function聲明的變數和var聲明的變數重名時,function的變數權重會比var聲明的要高。
下麵多來幾個例子解析一下就清楚許多了,但是看例子之前要知道一下什麼叫作用域。
二、作用域
作用域就是:起作用的範圍分為下麵兩種
1.全局作用域
2.函數作用域
他們兩個的區別看下麵的例子仔細分析。
三、看幾個例子解析一下執行順序的步驟
1. 第一個例子:
var x = 5; a(); function a(){ alert(x); var x = 10; } alert(x);
解析過程
1,.尋找聲明 (看全局作用域)
var x;
function a(){}
2.執行
x = 5;
a() ------------->執行到這個函數的過程中在重新進行以上兩步
1,尋找聲明 var x; (函數作用域)
2. 執行
alert(x); 這個x在函數作用域中存在,並且還沒有執行到賦值的那一步,那麼彈出的東西就是undefined;
x = 10;
alert(x) 這裡彈窗是全局變數 5;
所以瀏覽器彈窗的內容是 undefined 5
2. 第二個例子
a() function a(){ alert(x); var x = 10; } alert(x);
解析過程 按照上面的例子一樣分析
1. 尋找聲明
function a(){}
2.執行
a()------------------------->函數
1.尋找聲明
var x;
2.執行
alert(x) 彈出未定義
x = 10;
alert(x); 這裡的x會從全局中尋找x,但是發現並沒有x,所 以瀏覽器會 報錯 x is not defined x沒有被定義
所以瀏覽器的彈出的內容是 undefined 報錯
我相信看了這兩個例子的人都對這個解析過程都有了清除的瞭解,如果還是不太瞭解,建議重新看一次。
下麵介紹幾個需要註意的地方, 直接上例子
3. 第三個例子
前面講到了當function聲明的變數和var聲明的變數重名時,function的變數權重會比var聲明的要高。來一個例子證明一下
alert(a) function a() { alert("函數") } var a = 1; alert(a)
解析過程
1.尋找聲明
function a(){}
var a;
2. 執行
alert(a) 前面說到了function的聲明比var聲明的權重高,所有執行這個的時候他會彈出這個 函數塊(函數體)
a = 1;
alert(a); 這裡彈出的就是 1 了
所以最後的結果就是 函數塊 1;
4.第四個例子
子作用域可以向父級作用域找變數,直到全局作用域為止,反之不行。 如果子作用域有同樣的變數,那麼他就會使用自己的,不會去找爸爸要。
var a = 5; function fn() { alert(a) } fn()
解析過程
1.尋找聲明
var a;
function fn(){}
2.執行
a = 5;
fn()--------------------------------------> 函數
1.找聲明
2.執行
alert(a); 他這裡沒有a 所以去找爸爸要。 a = 5; 所以彈窗是 5
所以最後結果為 彈窗5
下麵看一下爸爸會不會去找兒子要東西
function fn(){ var b = 5; return b; } fn(); alert(b);
1.尋找聲明
function fn(){}
2. 執行
fn()----------------------------------------> 函數
1.尋找聲明
1.var b;
2.執行
return b;
alert(b); //我們看一下返回值是多少 b is not defined 他說b沒有被定義,說明父作用域不可以向自作用域去尋找變數。
5. 第五個例子
當一個變數無中生有時,不管從哪個作用域出來的,統統歸到window下,下麵看兩個例子
fn(); alert(a); var a = 0; alert(a); function fn(){ var a = 1; }
這一個例子應該可以自己分析了 最後的結果是 undefined 0
我們再來看一下下麵這個你會很吃驚
fn() alert(a) var a = 0; alert(a); function fn(){ a = 1; }
明明都一樣,我吃驚什麼 返回值不是還是 undefined 和 0 嗎
但是你有沒有發現倒數第二行 上面的聲明瞭 下麵的沒有聲明,來解析一波
1.尋找變數
var a;
function fn(){}
2.fn()---------------------------->函數
a = 1; 這個時候就說到了那一點,無中生有的變數,統統歸到window下麵
所以下麵的執行過程
alert(a) 這裡的彈窗就是 1 了
a = 0;
alert(a) 彈出 0
所以最後的結果是 1 0
四、嚴格模式
嚴格模式下的代碼執行時,非常嚴格
變數不允許無中生有
意義:規範代碼開發的流暢,邏輯
"use strict" a = 1; alert(a);
當我們寫後面兩句代碼的時候不會報錯和出現問題,但是當我們加上第一句代碼的時候,我們在這樣寫的時候就會報錯了。所以我們還是按照規範的標準來,提高自己的能力
五、可能好多人做了上面的例子感覺不太過癮,下麵我再給出幾個例子,可以自己去分析分析,我會在最後面給出答案。
1. 第一個例子 // 10 報錯
var a = 10; alert(a); a() function a(){ alert(20); }
2.第二個例子 undefined 1 0
var a = 0; function fn(){ alert(a); var a = 1; alert(a); } fn(); alert(a);
3.第三個例子 當同樣的聲明同樣的名字重覆時,後面寫的會覆蓋前面寫的 //2 1 1 3
a() var a = function(){ alert(1) } a(); function a(){ alert(2); } a(); var a = function(){ alert(3); } a()
如果你看到我的文章可以收穫一些知識,那麼我會非常高興的。