1. 程式人生 > >【詳解JavaScript系列】JavaScript之變數

【詳解JavaScript系列】JavaScript之變數

一  概述

    本篇文章將講解JavaScript中的變數,大致內容歸結為:

1.變數定義

包括變數宣告和變數初始化

2.變數種類

包括區域性變數和全域性變數

3.變數鏈式作用域及訪問

二  內容

(一)變數定義

        在JavaScript程式語言中,變數的定義是通過var關鍵字來定義的(若變數不通過var定義,則視為全域性變數,但不推薦這麼做,因為這樣做,在某些條件下,會引發一些問題)

1.變數宣告

1 var name;//變數宣告

2.變數初始化

1 name = "Alan_beijing";//變數初始化

當然,也像後端語言一樣(如java,.NET)一樣,在宣告變數的同時,給變數初始化。因此,如上兩句程式碼可如下定義:

1 var name = "Alan_beijing";//變數宣告同時初始化

(二)變數種類

在JavaScript中,若按照變數作用域和變數生命週期來劃分,可將變數分為全域性變數和區域性變數。

1.全域性變數:從作用域角度,全域性變數位於作用域鏈的最頂端;從變數生命週期角度,全域性變數生存期為整個程式生命週期,即直到程式結束,全域性變數才銷燬。

1     var address = "Shanghai";//全域性變數
2     function GetUserInfo() {
3         var userName = "Alan_beijing";//userName區域性變數
4 return userName +"-"+ address; 5 } 6 console.log(GetUserInfo());//Alan_beijing-Shanghai 7 console.log(address);//Shanghai

2.區域性變數:從作用域角度,區域性變數位於特定的區域性域,如特定的函式內部;從變數生命週期角度,區域性變數宣告週期只在其所處的特定作用域內,超出該作用域,就失效。如函式變數,直在函式內部有效。

1 function GetUserInfo() {
2         var userName = "Alan_beijing";
3 return userName; 4 } 5 console.log(GetUserInfo());//Alan_beijing 6 console.log(userName);//報錯:userName is not defined

(三)變數鏈式作用域及訪問

JS中的變數作用域是通過this指標,從當前的作用域開始,從當前作用域由內向外查詢,直到找到位置,這裡分為幾個邏輯:

a.從當前作用域由內向外查詢,若找到,就停止查詢,否則,繼續查詢,直到查到window全域性作用域為止,若任然未找到,則會出錯,提示該變數未定義;

b.當內部作用域變數名與外部作用域變數名相同時,內部作用域的覆蓋外部作用域。

看看下面例子:

 1 var dateTime='2018-09-16';
 2 function GetUserInfo(){
 3     var age=120;
 4     var name="Alan_beijing";
 5     function Say(){
 6        var name="老王";
 7        var address="shanghai";
 8        console.log(address+"-"+name+"-"+age+"-"+dateTime);//shanghai-老王-2018-06-05
 9     }
10    return Say();
11 }
12 
13 
14 GetUserInfo();//shanghai-老王-120-2018-09-16

來分析一下變數及其作用域:

如上圖,有4個作用域,當函式執行如下語句時,發生如下過程:

1 console.log(address+"-"+name+"-"+age+"-"+dateTime);

a.js當前this環境作用域為4作用域;

b.this指標尋找變數:addresss,name,age,dateTime,從當前作用域向外作用域逐層尋找,直到尋找到變數為止,若尋找到最外層作用域任然沒找到,則會出錯,提示該變數未宣告;

c.當內外層變數相同時,內層變數覆蓋外層變數,如4作用域的name覆蓋3作用域的name;

 (四)拓展

1.非規範化定義全域性變數(不推薦)

定義全域性變數的另一種方式,就是不使用關鍵字var

1    function GlobalParam() {
2         userName = "Alan_beijing";
3     }
4     GlobalParam();
5     console.log(userName);//Alan_beijing

如上,我們只需呼叫GlobalParam()函式一次,userName變數就有了定義,就可以在函式外部訪問它了。如下定義,是訪問不了的。因為未呼叫函式GlobalParam(),從而變數userName就沒定義

1    function GlobalParam() {
2         userName = "Alan_beijing";
3     }
4     console.log(userName);//報錯:userName is not defined

儘管可以這樣定義全域性變數,但是不推薦這種方式。

(1)在區域性作用域中定義的變數,很難維護

(2)由於變數必須先宣告,再使用,若忽略var關鍵字,導致變數不會立刻有定義,而導致錯誤,如上程式碼即可證明

(3)在嚴格模式下,會出現錯誤ReferenceError錯誤

(4)可能出現區域性變數修改全域性變數危險。看看如下例子

1     var scope = "Global";//全域性變數
2     function setParam() {
3         scope = "Local";//區域性變數(導致區域性變數修改全域性變數危險)
4         return scope;
5     }
6     console.log(scope);//Global
7 
8     setParam();
9     console.log(scope); //Local

2.JavaScript中沒有塊級作用域

 在後端語言中,我們非常熟悉if和for語句,我們先來看看如下.net的for語句:

1 for (int i = 0; i < 2; i++)
2     {
3           int result = 0;
4           result =result+ i;
5      }

我們知道,在for語句中,定義了兩個變數i和result,這兩個變數只能在for語句有效,不能在for語句外訪問。同樣地,在if語句中的變數也只能在if內部訪問,外部不能訪問

1 if (true)
2   {
3       string userName = "Alan_beijing";
4   } 

不僅if和for語句,while,do...while,switch語句等,均是相同的,他們內部的變數,只能在其內部訪問,不能在其外部訪問,我們將其稱之為“塊級作用域”;

然而,在JavaScript中,是沒有塊級作用域的。

1     var maxNum = 100;
2     for (var i = 0; i < maxNum; i++) {
3         var sum = 0;
4         sum = sum + i;
5     }
6     console.log(sum);//99。因為JavaScript沒有塊級作用域,因此能在for語句外部訪問變數sum

3.JavaScript中this指標

4.JavaScript鏈式作用域

(五)例子

請分析如下例子的結果。

 1    var address = "Shanghai";//全域性變數
 2     function GetUserInfo() {
 3         var userName = "Alan_beijing";//userName區域性變數
 4         return userName +"-"+ address;
 5     }
 6     console.log(GetUserInfo());//Alan_beijing-Shanghai
 7     console.log(address);//Shanghai
 8     console.log(window.address);//Shanghai
 9     console.log(window.userName);//undefined
10     console.log(userName);//報錯:userName is not defined

三   已釋出文章