寫了10年Javascript未必全瞭解的標識符順序

一,局部變量先使用後聲明,不影響外部同名變量

Js代碼 
  1. var x = 1; // --> 外部變量x  
  2. function fn(){  
  3.     alert(x);  // --> undefined 局部變量x先使用  
  4.     var x = 2; // 後聲明且賦值  
  5. }  
  6. fn();  
  7. alert(x); // --> 1  

 

第一點,函數fn內第一句輸出x,x是在第二句才定義的。這在js中是容許的,這裏的容許是指不會出現語法錯誤程序能夠運行。
但在其它語言如C,Java中倒是不容許的。變量必選先聲明後使用,如:javascript

Java代碼 
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         System.out.println(x); // 先使用  
  4.         int x = 10// 後聲明  
  5.     }  
  6. }  

 

Java中編譯器會提示錯誤,程序沒法運行。

第二點,函數fn內的局部變量x不會影響到外部的變量x。即fn內alert輸出不是1,而是undefined。

順便提下,這段代碼常常出如今前端面試題中。前端

 

 

二,形參優先級高於函數名

Js代碼 
  1. function fn(fn){  
  2.     alert(fn);  
  3. }  
  4. fn('hello'); // --> "hello"  

 

能夠看到函數名和形參同名都是fn,輸出的是字符串"hello",卻不是函數fn的函數體(fn.toString())。java

 

 

三,形參優先級高於arguments

Js代碼 
  1. function fn(arguments){  
  2.     alert(arguments);  
  3. }  
  4. fn('hello'); // --> "hello"  

 

arguments對象能夠直接在函數內使用,是語言自己提供的標識符。
這裏恰好將形參聲明成與其同名。輸出能夠看到是"hello"而非"[object Object]",即形參arguments覆蓋了語言自己提供的真正的arguments。面試

 

 

四,形參優先級高於只聲明卻未賦值的局部變量

Js代碼 
  1. function fn(a){  
  2.     var a;  
  3.     alert(a);  
  4. }  
  5. fn('hello'); // --> "hello"  

 

函數fn形參爲a,函數內第一句僅聲明局部變量a,卻並未賦值。從輸出結果是"hello"而非undefined能夠看出形參a優先級高於僅聲明卻未賦值的局部變量a。app

 

 

五,聲明且賦值的局部變量優先級高於形參

Js代碼 
  1. function fn(a){  
  2.     var a = 1;  
  3.     alert(a);  
  4. }  
  5. fn('hello'); // --> "1"  

 

函數fn形參爲a,函數內第一句僅聲明局部變量a,賦值爲1。從輸出結果是"1"而非"hello"能夠看出聲明且賦值的局部變量a優先級高於形參a。函數

 

 

六,瞭解了以上幾點,再看一個有趣的代碼

Js代碼 
  1. function fn(a){  
  2.     var a = a;  
  3.     alert(a);  
  4. }  
  5. fn('hello');  

 

暫不運行,猜想下結果。若是按照第五點:聲明且賦值的局部變量優先級高於形參。那麼a將是undefined。但實際上a是"hello",即右a是形參a,左a纔是局部變量a。spa

 

這裏的兩個a互不干擾,誰也沒覆蓋誰。這與剛剛說的賦值的局部變量優先級高於形參又矛盾了。但引擎這樣作的確是咱們想要的,由於並不但願var a = a後a是undefined。對象

 

知識點深刻:http://www.javaeye.com/topic/802482#1741032ip

相關文章
相關標籤/搜索