首頁 web前端 js教程 JavaScript變數作用域分類與使用技巧實例詳解

JavaScript變數作用域分類與使用技巧實例詳解

Jul 18, 2017 am 10:23 AM
javascript 作用域 使用技巧

變數作用域是每門程式語言都會涉及的話題,也是身為程式設計師必需掌握的知識點,能深入掌握變數作用域更有助於你編寫穩定的程式。

一、JavaScript作用域分類
JavaScript就兩種作用域:全域(window)、函數級(function)。函數級(function)不要理解為「塊級(大括號{}級)」。

二、區分及定義JavaScript全域變數與局部變數
1.1定義在所有函數最外邊,使用或不使用var關鍵字定義的變數都是全域變數。全域變數其實被解析成window物件的屬性,所以我們可以以「window.全域變數名稱」方式存取它,建議在沒有必要的情況下直接使用變數名稱存取。如下範例示範了全域變數定義最常見的方法: 

var msg1='This is message 1'; 
msg2='This is message 2'; 
alert(window.msg1); //This is message 1 使用window关键字进行访问 
alert(window.msg2); //This is message 2 
alert(msg1); //This is message 1 省略window关键字的访问方式 
alert(msg2); //This is message 2 
function otherFunction(){} //其它一些函数或对象声明代码 
var otherObject={};
登入後複製


1.2在函數內(局部變數執行階段環境)一樣可以定義並取得全域變數。定義的方法就是不使用var關鍵字,在局部環境中亦可輕鬆取得全域變數內容,直接使用全域變數名稱引用即可。要注意的是:如果函數內定義了與全域變數同名的局部變量,那麼此時函數體將優先使用自己的局部變量,如果此時你非要使用同名的全域變量,請加上window前綴。舉例如下: 

var msg1='This is message 1'; 
var msg3='This is message 3'; 
function otherFunction() 
{ 
msg2='This is message 2'; //不使用var关键字,其实也是定义一个全局变量 
var msg3='Message 3'; 
alert(msg1); //This is message 1 (函数内当然可以访问到外面定义的全局变量,再深的函数嵌套一样能正确获到这个全局变量,这是JavaScript闭包的其中一种体现) 
alert(msg3); //Message 3 (局部变量msg3) 
alert(window.msg3); //This is message 3 (使用window前缀访问同名的全局变量msg3) 
alert(this.msg3); //This is message 3 (因为otherFunction ()定义在一个全局的环境中,此时otherFunction ()的this也是指向window,所有你看到window. msg3是等于this. msg3的) 
} 
otherFunction(); 
//otherFunction函数外面定义的msg1和里面定义的msg2依然是全局变量 
alert(window.msg1); //This is message 1 
alert(window.msg2); //This is message 2
登入後複製


2.1使用var關鍵字,在函數體內定義的變數是局部變量,此變數能供其下面所有語句區塊({})及子函數使用。這個變數在這個函數裡任何地方都可以訪問到,但卻不能在這個函數的外面「直接」訪問(閉包允許間接訪問,或代理訪問,此知識點不在本文討論範圍)。舉例如下: 

function showMsg() 
{ 
if (true) 
{ 
var msg='This is message'; 
} 
alert(msg); //This is message 
} 
showMsg(); 
alert(typeof(msg)); //undefiend 
//这里在if {}大括号内定义的变量msg还能在if外showMsg()内访问到,但在showMsg()外则是无法访问的
登入後複製


2.2父函數的變數可以被子函數訪問,但子函數的變數卻不能被父函數訪問,顯然這與我們一開始說的函數級作用域是相吻合的。這看起來老爸爽快些,兒子吝嗇些。舉例如下: 

function showMsg() 
{ 
var MsgA='Message A'; 
this.setMsg=function(msg) 
{ 
var MsgB='Message B'; 
alert(MsgA); //Message A (子函数setMsg()可以访问父函数showMsg()的局部变量MsgA) 
} 
alert(MsgB); //MsgB未定义 (在父函数中不能访问其子函数中定义的变量MsgB) 
} 
var sm=new showMsg(); 
sm.setMsg('Message string');
登入後複製


三、使用技巧
1、為了避免變數混亂或被覆蓋,對於局部變數的定義一定不要忘記加上var關鍵字(必要時我們要變數使用完後主動釋放它,即「變數名稱=null」),同時建議把所有變數集中定義在每個函數體內的開頭位置。舉例如下: 

var msg='Message'; 
function showMsg() 
{ 
var msg; //这里即使不小心使用了与全局变量一样的变量名,也不用担心覆盖同名全局变量的问题 
var a; 
var b; 
var c; 
for (a=0;a<10;a++){} 
this.setMsg=function(){} 
}
登入後複製


2、巧用匿名函數,減少命名衝突或變數污染。以下兩段程式碼其實實現了相同的功能,而第一段程式碼寫法自己可以在那個匿名函數內大膽用自己想用的變數名稱等,不用擔心自己定義的變數覆蓋其他人定義或自己其它地方定義的變數。 

//定义一个匿名函数,然后把代码丢到这个匿名函数里面,能有效减少命名冲突或变量污染,这是常见JS框架的做法 
(function() 
{ 
var msg=&#39;This is message&#39;; 
alert(msg); 
})(); 
document.write(msg); //msg未定义 (匿名函数外的其它方法已无法调用msg这个变量) 
//----------------------------- 
var msg=&#39;This is message&#39;; 
alert(msg);
登入後複製


3、不建議在無須實例化的函數內使用this取代window去存取全域變數。一般情況使用this關鍵字的函數應作為JavaScript類別來處理(我喜歡把「cls」當作類別名稱的前綴)。以下函數如果只當作普通函數呼叫一下,就不應該出現this關鍵字,因為這通常是去操作一個全域變數了。例: 

function clsMsg() 
{ 
this.msg=&#39;This is default message&#39;; 
this.showMsg=function() 
{ 
alert(this.msg); 
} 
} 
sMsg=new clsMsg(); 
sMsg.msg=&#39;This is new message&#39;; 
sMsg.showMsg();
登入後複製

以上是JavaScript變數作用域分類與使用技巧實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

c語言中typedef struct的用法 c語言中typedef struct的用法 May 09, 2024 am 10:15 AM

typedef struct 在 C 語言中用於建立結構體類型別名,簡化結構體使用。它透過指定結構體別名將一個新的資料類型作為現有結構體的別名。優點包括增強可讀性、程式碼重複使用和類型檢查。注意:在使用別名前必須定義結構體,別名在程式中必須唯一且僅在其宣告的作用域內有效。

java中的variable expected怎麼解決 java中的variable expected怎麼解決 May 07, 2024 am 02:48 AM

Java 中的變數期望值異常可以透過以下方法解決:初始化變數;使用預設值;使用 null 值;使用檢查和賦值;了解局部變數的作用域。

js中閉包的優缺點 js中閉包的優缺點 May 10, 2024 am 04:39 AM

JavaScript 閉包的優點包括維持變數作用域、實作模組化程式碼、延遲執行和事件處理;缺點包括記憶體洩漏、增加了複雜性、效能開銷和作用域鏈影響。

c++中的include什麼意思 c++中的include什麼意思 May 09, 2024 am 01:45 AM

C++ 中的 #include 預處理器指令將外部來源檔案的內容插入到目前原始檔案中,以複製其內容到目前原始檔案的相應位置。主要用於包含頭文件,這些頭文件包含程式碼中所需的聲明,例如 #include <iostream> 是包含標準輸入/輸出函數。

C++ 智慧指標:全面剖析其生命週期 C++ 智慧指標:全面剖析其生命週期 May 09, 2024 am 11:06 AM

C++智慧指標的生命週期:建立:分配記憶體時建立智慧指標。所有權轉移:透過移動操作轉移所有權。釋放:智慧指標離開作用域或被明確釋放時釋放記憶體。物件銷毀:所指向物件被銷毀時,智慧型指標成為無效指標。

c++中函數的定義和呼叫可以巢狀嗎 c++中函數的定義和呼叫可以巢狀嗎 May 06, 2024 pm 06:36 PM

可以。 C++ 允許函數巢狀定義和呼叫。外部函數可定義內建函數,內部函數可在作用域內直接呼叫。巢狀函數增強了封裝性、可重複用性和作用域控制。但內部函數無法直接存取外部函數的局部變量,且傳回值類型需與外部函數宣告一致,內部函數不能自遞歸。

vue中let和var的區別 vue中let和var的區別 May 08, 2024 pm 04:21 PM

在 Vue 中,let 和 var 宣告變數時在作用域上存在差異:作用域:var 具有全域作用域,let 具有區塊級作用域。區塊級作用域:var 不會建立區塊級作用域,let 建立區塊級作用域。重新宣告:var 允許在同一作用域內重新宣告變數,let 不允許。

C++ 智慧指標:從基礎到高級 C++ 智慧指標:從基礎到高級 May 09, 2024 pm 09:27 PM

智慧指針是C++專用指針,能夠自動釋放堆記憶體對象,避免記憶體錯誤。類型包括:unique_ptr:獨佔所有權,指向單一物件。 shared_ptr:共享所有權,允許多個指標同時管理物件。 weak_ptr:弱引用,不增加引用計數,避免循環引用。使用方法:使用std命名空間的make_unique、make_shared和make_weak建立智慧指標。智慧型指標在作用域結束時自動釋放物件記憶體。進階用法:可以使用自訂刪除器控制物件釋放方式。智慧型指標可有效管理動態數組,防止記憶體洩漏。

See all articles