JavaScript局部變數與全域變數1

來源:互聯網
上載者:User

在一個函數中(或類定義中),有用var定義的變數為局部變數,沒有定義就賦值的是全域變數。沒有定義就使用的,IE提示錯誤“'x'未定義”。
好象很簡單,但自己實際去試一下才發現問題多多。

 

我寫一個函數,然後在VS2005中調試,我就想看一看在開發環境如何看出是局部變數與全域變數。
function abc()
{
 var i=0;
 a=1;
 i=a;
}

abc();
var o1=abc;
alert(o1.i); //提示undefined
alert(a);    //提示1
debugger;    //快速監視this,但找不到a,只有監視this.a才出現
結果,雖然a是正確地提示出來,但我無法在快速監視this中看到a,只有快速監視this.a才能看到。這裡的this為window。VS2008會如何?(後面,在調試中的局部視窗中可以看到this的東西)

 

如果用類的方式來寫:
var abc=function()
{
 var i;

 a=1;   //相當於建構函式
 i=a;
}

var o1=new abc();
alert(o1.i);
alert(a);
debugger;
得到的結果是一樣的,我都監視不到明顯的類的屬性。

對比我的函數寫法,以及別人的類寫法,發現一個學習點:
var o1=abc;        //讓o1等於abc,因此其它地方可以執行o1();也就是執行abc();,

typeof(o1)="function"
var o1=abc();      //執行abc,並把傳回值給o1,typeof(o1)="undefined"
var o1=new abc();  //o1為類abc的執行個體,該代碼也會執行函數abc,不過這美其名曰“建構函式”,typeof(o1)="object"
對比一下,發現還是“外國的月亮圓”,別人的代碼強!

 

再對比一下,還有function的寫法不一樣,下面的寫法被稱為匿名函數,上面的寫法則是普通寫法,但據說上面寫的同時,javaScript也產生了一個同名對象。
我再找,總算在VS2005中找到了它,以及前面提到的私人變數與全域變數。在“調試”菜單的“視窗”子功能表的“局部變數”中可以看到對應的局部變數。
有了這個視窗,我現在應該敢懷疑這句話“上面寫的同時,javaScript也產生了一個同名對象”,或者我理解錯了作者原意。反正,系統裡面只有一個該名字的對象,其typeof的值為function,而不是該名字的對象有兩個,一個object,一個function。

 

function比string這些簡單類型更牛的是:function可以這樣
abc.i=2;
而string這些簡單類型就不能這樣了:
var s="OK";
s.i=9;  //這樣也不行:s.prototype.i=9;

 

存取全域變數速度比局部變數要慢得多
用以下網頁來驗證
<html>
<head>
<script>

var a = new Date();
a1();
document.write((new Date() - a) + ":");

a = new Date();
a2();
document.write((new Date() - a) + "  ");

a = new Date();
a3();
document.write((new Date() - a) + ":");

a = new Date();
a4();
document.write((new Date() - a) + "  ");

//設定全域變數
function a1()
{
 var i;
 for (i=0; i<100000; i++)
 {
  b=1;
 }
}

//設定局部變數
function a2()
{
 var i;
 var b;
 for (i=0; i<100000; i++)
 {
  b=1;
 }
}

//讀取全域變數
function a3()
{
 var i;
 c=2;
 var b;
 for (i=0; i<100000; i++)
 {
  b=c;
 }
}

//讀取局部變數
function a4()
{
 var i;
 var c=2;
 var b;
 for (i=0; i<100000; i++)
 {
  b=c;
 }
}

</script>
</head>
<body>
</body>
</html>
執行結果為:109:78 94:62 不是固定這個值,但能說明全域變數比局部變數慢30-40%。看來“存取全域變數速度比局部變數要慢得多”這句話沒錯!

 

如果要頻繁使用全域變數,可以設定一個局部變數,先把全域變數拷貝過來再使用。
這句會不會又有什麼問題?
如果是向上面的測試代碼,拷貝過來應該是沒有問題的。但如果全域變數是在變化之中的話,拷貝過來會跟著變化嗎?
以下代碼做這個測試:
<html>
<head>
<script>

function a1()
{
 var i;
 a=2;
 var b;
 b=a;

 a=3;
 alert(b);  //顯示2

 b=4;
 alert(a);  //顯示3
}

function a2()
{
 var i;
 a=new Object();
 var b;
 b=a;

 a.i=5;
 alert(b.i);  //顯示5

 b.i=6;
 alert(a.i);  //顯示6
}

function a3()
{
 var i;
 a=new Object();
 var b;
 b=a;

 a.i=5;
 alert(b.i);  //顯示5

 a=new Object();
 a.i=6;
 alert(b.i);  //顯示5
}

a1();
a2();

</script>
</head>
<body>
</body>
</html>
測試時發現,如果a是簡單類型,b=a也只是值的拷貝,因此如果全域變數變化了,不會反映到局部變數。如果a是物件類型,b=a就是地址的拷貝,因此如果全域變數下面的屬性變化了,可以反映到局部變數中。但如果是a變成新的對象時,b的引用又不對了。
因此可以說,要想用拷貝全域變數來加快速度,程式員要考慮在使用過程中是否值有沒有被更改,或對象有沒有建立過。

 

VS進入到with時,會有什麼反應
<html>
<body>
<script>
 var i=12;
 var a=new Object();
 a.i=5;
 a.j=6;
 with (a)
 {
  temp=i;
  i=j;
  j=temp;
 }
 alert(i);
</script>
</body>
</html>
從代碼中要記住with的格式,後面帶一個圓括弧,中間為想節省的對象,後面再帶一個代碼塊。中間如果有使用對象的屬性,就自動引用,而使用非對象的屬性,則當做外面的普通變數處理。
進入with後,VS好象沒有什麼變化,至少“局部變數”視窗沒有什麼變化。但提示功能中對i的提示,就自動使用a.i的值了。出來後,又繼續提示全域變數i的值了。
這裡看,用於with確實可能造成一定的混亂,難怪JsLint不建議使用。

 

我現在編寫javascript還沒到會用try...catch的地步,先小試一個:
<html>
<body>
<script>
{
 var a=b;
}
catch(e)
{
 alert("       e.name:" + e.name + "\n" +
       "    e.message:" + e.message + "\n" +
       "     e.number:" + e.number.toString(16) + "\n" +
       "e.description:" + e.description);
 a=1;
}
finally
{
 alert(a);
}
</script>
</body>
</html>
有點像VB中的on error goto xxx。如果按照我的編程原則,對已知的錯誤,要想辦法避免,對未知的錯誤,應該要提示出來,並且程式停止(就是使用系統內建的功能),這樣使用者才會有向你報怨。對無法避免的已知錯誤,才需要使用on error goto xxx。我在JavaScript中太多未知的錯誤,因此至今還沒有哪個需要用到try來防止錯誤重複發生。
這裡會提到try...catch是因為變數e只是在catch作用區內才有效,但我測試時,卻發現事實卻非如此。e好象是全程有效。因此取名不要亂取,不要與其它全域變數重名了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.