JS 聲明變量的三種方式
(1)使用變量步驟:a.聲明-->b.賦值-->3.調用
正確用法:
<script type="text/javascript"> // 方式一:聲明和賦值不分離 var correctUsage = "正確使用變量的方式一"; alert(correctUsage); //能夠彈出來該變量所對應的值 // 方式二:聲明和賦值分離 var correctUsage2; correctUsage2 = "正確使用變量的方式二"; alert(correctUsage2); </script>
錯誤用法:
<script type="text/javascript"> var correctUsage; // 錯誤一: 沒有賦值就使用 alert(correctUsage); //underfined // 錯誤二:沒有賦值就拼接字符串 correctUsage += "沒有賦值就改值"; alert(correctUsage); //undefined沒有賦值就改值 </script>
(2)變量的產生與死亡
已使用var關鍵詞聲明表里為例
2.1 聲明在函數外部的變量
產生:js加載到該變量所在行時產生
死亡:js代碼加載完畢,變量死亡
2.2聲明在函數內部的變量
前提:該變量所在的函數被調用
產生:js執行到該變量所在行時產生
死亡: 該變量所在的函數執行行結束
舉例:
情景一:函數只聲明,不調用
<script type="text/javascript"> function test(){ var aa = "test"; aa +="只聲明,但不調用該函數時,該函數會不會執行?"; //添加內容 alert(aa); aa = "該函數的變量不會執行!"; alert(aa); } </script>
說明:上面2個alert不會執行
情景二:聲明並調用該函數
function test(){ var aa = "test"; aa +="只聲明,但不調用該函數時,該函數會不會執行?"; //添加內容 alert(aa); aa = "該函數的變量不會執行!"; alert(aa); } test();
說明:上面2個alert均會執行
(3)全局變量與局部變量
3.1全局變量
聲明在函數體外,任何地方都可訪問到該變量
3.2局部變量
聲明在函數體內,只有在函數體內可訪問到該變量
(4)聲明變量的3種方式及作用域
4.1使用var (最常見)
var聲明的變量可以是全局的(函數外面),也可以是函數級的(函數內部)
function test() { globalVar = "這是一個全局變量"; var partialVar = "這是一個局部變量"; } test(); alert(globalVar); //這是一個全局變量 alert(partialVar); //直接報錯
說明:函數內部聲明變量的時候,一定要使用var命令,如果不用的話,你實際上聲明了一個全局變量
情景一:
var varLocation = "函數外部聲明並賦值"; function test(){ varLocation = "函數內部改值"; alert(varLocation); // 函數內部改值 } test(); alert(varLocation); // 函數內部改值
說明:函數外面聲明的變量,在函數內部改變該值后,函數外面的該變量的值也隨之改變
情景二:
var varLocation = "函數外部聲明並賦值"; function test(){ var varLocation = "函數內部改值"; alert(varLocation); // 函數內部改值 } test(); alert(varLocation); // 函數內部改值
說明:在函數外面使用var聲明一個變量后,再在函數內部使用var再次聲明一次並改變其值,函數外面的該變量的值不會發生改變。
4.2 使用const
const用於修飾常量,定義的變量不可修改,而且必須初始化,聲明位置不限(通常聲明在js開頭),與java類的final關鍵字性質一樣
舉例:
function test(){ const testConstant = "測試常量"; alert(testConstant); testConstant = "改變常量值"; } test();
4.3 使用let
let聲明的變量在{}中使用,變量的作用域限制在塊級域中
舉例:使用js動態給ul添加li對象並點擊第幾項,顯示當前點擊是第幾個
window.onload = function(){ var ul = document.getElementById("ulList"); for(var i = 0 i <= 5; i++){ // 創建一個li對象 var li = document.createElement("li"); // li標簽內內容設置為:Itemi li.appendChild(document.createTextNode("Item" + i)); // 聲明一個塊級變量j,並將i賦給j let j = i; // 綁定點擊事件 li.onclick = function(){ alert("Item" + i + "is clicked."); }; ul.appendClild(li); } }
錯誤方式:
window.onload = function(){ var ul = document.getElementById("ulList"); for(var i = 0 i <= 5; i++){ // 創建一個li對象 var li = document.createElement("li"); // li標簽內內容設置為:Itemi li.appendChild(document.createTextNode("Item" + i)); // 綁定點擊事件 li.onclick = function(){ alert("Item" + i + "is clicked."); }; ul.appendClild(li); } }
結果:點擊每個li,提示的都是“Item 6 is clicked.”
擴展:使用var如何實現這種效果?閉包
window.onload = function(){ var ul = document.getElementById("ulList"); for(var i = 0 i <= 5; i++){ // 創建一個li對象 var li = document.createElement("li"); // li標簽內內容設置為:Itemi li.appendChild(document.createTextNode("Item" + i)); // 綁定點擊事件 li.onclick = (function(i){ return function (){ alert("Item" + i + "is clicked."); }; })(i) // 閉包 // 將LI對象item拼接到UL標簽體內 ul.appendClild(li); } }
說明:采用的閉包的方式在綁定的時候已經把j的值已經傳遞給對應的click事件了,所以能夠實現相同的結果,但是,從程序的可維護性來說不推薦使用。
4.4 聲明變量的要項
4.4.1 js聲明的變量取值的原則:就近原則;
4.4.2 js是弱類型語言,不同的數據類型可以用同一個變量名表示;
4.4.3 函數內部聲明的變量,不會影響函數外部同名的變量的值。
舉例:
var testVarValue = "測試就近原則"; <script type="text/javascript"> function test() { const testRepeatStatement = "測試用一個變量賦予不同的類型及不同的值"; alert(testRepeatStatement); //測試用一個變量賦予不同的類型及不同的值 } test(); </script>
(5)如何避免全局污染?
方法:閉包
舉例:
(function(){ // 聲明一個JSON對象 var JsonObj = {}; //定義該對象的屬性及屬性值 JsonObj.name = "對象的屬性"; JsonObj.method = function() { alert("測試是否能夠調用該方法"); return JsonObj.name; } // 通過操作window對象,供外部訪問該對象的屬性和方法 window.GlobalObj = JsonObj; })(); // 調取該對象的方法並接受返回值 var name = GlobalObj.method(); // 獲取的是返回值name alert(name); //對象屬性 // 只獲取該方法但不調用 var method = GlobalObj.method; // 獲取的是對象GlobalObj2的method1()方法 alert(method); // function (){ // alert("測試是否能夠調用該方法"); // return JsonObj.name; //} // 調用接受到的方法,但不接受返回值 method();
閉包的優缺點說明:
優點:設計私有的方法和變量,保護函數內的變量安全;
弊端:閉包有一個非常嚴重的問題,那就是內存浪費問題,這個內存浪費不僅僅因為它常駐內存,更重要的是,對閉包的使用不當會造成無效內存的產生。