js變數範圍及可訪問性的探討

來源:互聯網
上載者:User
js|變數|訪問

每一種語言都有變數的概念,變數是用來儲存資訊的一個元素。比如下面這個函數:

 1function Student(name,age,from)
 2{
 3 this.name = name;
 4 this.age = age;
 5 this.from = from;
 6 this.ToString = function()
 7 {
 8  return "my information is name: "+this.name+",age : "+this.age+", from :" +this.from;
 9 }
10}
   Student類有三個變數,分別為name(名字),age(年齡),from(籍貫),這三個變數構成了描述一個對象的資訊。當然,這裡還有一個方法用來返回Student的資訊。
   但是,我們是不是定義了一個變數,它就能一直存在著,並且還有可能在任何地方都能被訪問和使用直到其被銷毀?仔細想想,上面的需求是比較過分的,因為某些變數在某個功能實現後就不再利用了,但如果這個變數還存在的話,就佔用了系統資源了,俗語曰:“站著茅坑不拉#$%”。
   於是我們對變數的及時和按需求地銷毀有一個探討的話題了。
   好,切入正題吧,就本人所接觸過的來講,js中支援如下幾種類型的變數,分別為:局部變數、類變數、私人變數、執行個體變數、靜態變數和全域變數。接下來我們就一一探討研究下。

局部變數:

局部變數一般指在{}範圍內有效變數,也就是語句塊內有效變數,如:

 1function foo(flag)
 2{
 3 var sum = 0;
 4 if(flag == true)
 5 {
 6  var index;
 7  for(index=0;index<10;index++)
 8  {
 9   sum +=index;
10  }
11 }
12 document.write("index is :"+index+"<br>");
13 return sum;
14}
15//document.write("sum is :" +sum+"<br>");
16document.write("result is :"+foo(true)+"<br>");
   該代碼執行後輸出的結果為:“index is :undefined” 和 “result is :0”,我們可以看到希望輸出的index變數的值為undefined,也就是未定義。因此我們可以發現,index變數在if語句塊結束後即被銷毀了。那麼“sum”變數呢?這個變數在foo()函數段執行完畢後被銷毀了,如果您去掉我注釋的那條語句,再執行,您將會發現系統將報錯。值得注意的是,如果我把上面的foo()函數改成如下:

 1function foo(flag)
 2{
 3 var sum = 0;
 4 for(var index=0;index<10;index++)
 5 {
 6  sum +=index;
 7 }
 8 document.write("index is :"+index+"<br>");
 9 return sum;
10}

   您將可以看見可以輸出index值("index is :10"),這個是js和其他語言的不同地方,因為index是在for迴圈的{}外面定義的,因此其作用範圍在foo()函數使用完畢後才銷毀。

  類變數:
   類變數,實際上就是類的一個屬性或欄位或一個方法,該變數在該類的一個執行個體對象被銷毀後自動銷毀,比如我們開始時舉的Student類。這個我們不多討論,大家可以自己試一下。

私人變數:
   私人變數,值得是某個類自己內部是用的一個屬性,外部無法調用,其定義是用 var 來聲明的。注意如果不用var 來聲明,該變數將是全域變數(我們下面將會討論),如:

 1function Student(name,age,from)
 2{
 3
 4 this.name = FormatIt(name);
 5 this.age = age;
 6 this.from = from;
 7 var origName = name;
 8 var FormatIt = function(name)
 9 {
10  return name.substr(0,5);
11 }
12 this.ToString = function()
13 {
14  return "my information is name: "+origName+",age : "+this.age+", from :" +this.from;
15 }
16}
17
18
   這裡,我們分別定義了一個origName和FormatIt()兩個私人變數(按物件導向的解釋,應該用類的屬性來稱呼)。
   我們把這種情況下的方法也成為變數,因為該情況下的變數是個function類型的變數,而function也屬於Object類的繼承類。在這種情形下,如果我們定義了 var zfp = new Student("3zfp",100,"ShenZhen")。但無法通過zfp.origName和zfp.FormatIt()方式來訪問這兩個變數的。

注意以下幾點:

1、私人變數是不能用this來指示的。
2、私人方法類型的變數的調用必須是在該方法聲明後。如我們將Student類改造如下:

 1function Student(name,age,from)
 2{
 3 var origName = name;
 4 this.name = FormatName(name);
 5 this.age = age;
 6 this.from = from;
 7 var FormatName = function(name)
 8 {
 9  return name+".china";
10 }
11 this.ToString = function()
12 {
13  return "my information is name: "+origName+",age : "+this.age+", from :" +this.from;
14 }
15}
16var zfp = new Student("3zfp",100,"ShenZhen");
代碼執行後,將會報"找不到對象"的錯誤.意思是FormatName()未定義。

3、私人方法無法訪問this指示的變數(公開變數),如下:

 1
 2function Student(basicinfo)
 3{
 4 this.basicInfo = basicinfo;
 5
 6 var FormatInfo = function()
 7 {
 8  this.basicInfo.name = this.basicInfo.name+".china";
 9 }
10 FormatInfo();
11
12}
13function BasicInfo(name,age,from)
14{
15 this.name = name;
16 this.age = age;
17 this.from = from;
18}
19var zfp = new Student(new BasicInfo("3zfp",100,"ShenZhen"));
20
21
執行代碼後,系統將會提示 “this.basicInfo為空白或不是對象”的錯誤。
基本結論是,私人方法只能訪問私人屬性,私人屬性在聲明並賦值後可以在類的任何地方訪問,

執行個體變數:
執行個體變數即某個執行個體對象所擁有的變數。如:

 1
 2function BasicInfo(name,age,from)
 3{
 4 this.name = name;
 5 this.age = age;
 6 this.from = from;
 7}
 8var basicA = new BasicInfo("3zfp",100,"ShenZhen");
 9basicA.generalInfo = "is 3zfp owned object";
10document.write("basicA's generalInfo is : "+ basicA.generalInfo+"<br>");
11var basicB = new BasicInfo("zfp",100,"ShenZhen");
12document.write("basicB's generalInfo is : "+ basicB.generalInfo+"<br>");
13執行該代碼後,我們將可以看到如下結果:
14basicA's generalInfo is : is 3zfp owned object
15basicB's generalInfo is : undefined
16
靜態變數:

靜態變數即為某個類所擁有的屬性,通過 類名+"."+靜態變數名 的方式訪問該屬性。如下可以做清晰的解釋:

 1function BasicInfo(name,age,from)
 2{
 3 this.name = name;
 4 this.age = age;
 5 this.from = from;
 6}
 7BasicInfo.generalInfo = "is 3zfp owned object";
 8var basic = new BasicInfo("zfp",100,"ShenZhen");
 9document.write(basic.generalInfo+"<br>");
10document.write(BasicInfo.generalInfo+"<br>");
11BasicInfo.generalInfo = "info is changed";
12document.write(BasicInfo.generalInfo+"<br>");
執行以上代碼,將會得到如下結果:
undefined
is 3zfp owned object
info is changed

注意以下幾點:
1、以 類名+"."+靜態變數名 的方式來聲明一個靜態變數
2、靜態變數並不屬於類的某個執行個體對象所專屬的屬性,為對象的共用.
3、能以執行個體對象名+"."+靜態變數名來訪問。

全域變數:
全域變數即整個系統運行期間有效存取控制的變數,通常是在一個js代碼開頭定義,如:

1
2var copyright = "3zfp owned";
3var foo =function()
4{
5 window.alert(copyright);
6}
注意以下幾點:

1、如果一個變數不用var 來聲明,則其被視為全域變數。如:

1var copyright = "3zfp owned";
2var foo =function(fooInfo)
3{
4 _foo = fooInfo;
5 document.write(copyright+"<br>");
6}
7new foo("foo test");
8document.write(_foo+"<br>");
執行代碼,將得到如下結果:
3zfp owned
foo test
但是,這個又有一個注意的地方,function是編譯期對象,也就是說_foo這個全域變數要在foo對象被執行個體化後才能被初始化,也就是說如果將
new foo();
document.write(_foo+"<br>");
對調成
document.write(_foo+"<br>");
new foo();
系統將提示 "_foo 未定義"。
2、如果定義了一個和全域變數同名的局部變數屬性,如下:

 1
 2
 3var copyright = "3zfp owned";
 4var foo =function(fooInfo)
 5{
 6 var copyright = fooInfo; //同名變數
 7 this.showInfo = function()
 8 {
 9  document.write(copyright+"<br>");
10 }
11}
12new foo("foo test").showInfo();
13document.write(copyright+"<br>");
執行代碼,將得到如下結果:
3zfp owned
foo test

原因是由於function 是在編譯期間完成變數的定義,也就是foo內部的copyright的定義是在編譯期間完成的,其範圍只在foo對象內有效,而與外部定義的全域變數copyright無關。



相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

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

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