搜尋
首頁web前端js教程Javascript學習筆記之函數篇(六) : 作用域與命名空間_基礎知識

在先前的介紹中,我們已經知道 Javascript 沒有區塊級作用,只有函數級作用域。

複製程式碼 程式碼如下:

function test() { // a scope
    for(var i = 0; i         // count
    }
    console.log(i); // 10
}

Javascript 中也沒有顯示的命名空間,這意味著一切都定義在全域作用域中。每次引用一個變數時,Javascript 都會往上遍歷整個全域作用域直到找到變數。如果遍歷完整個全域作用域仍然沒有找到該變量,則拋出一個 ReferenceError 錯誤。

請輸入圖片描述

隱式全域變數

複製程式碼 程式碼如下:

// script A
foo = '42';
// script B
var foo = '42'

上面的兩個例子產生不一樣的效果。第一個將在全域作用域中定義變數 foo,而第二個則在目前作用域定義變數 foo。
我們一定要注意,如果不使用關鍵字 var 將會帶來意想不到的影響。

複製程式碼 程式碼如下:

// global scope
var foo = 42;
function test() {
    // local scope
    foo = 21;
}
test();
foo; // 21

由於在函數 test 內沒用 var 來定義變數 foo,所以將覆蓋函數外部的全域變數 foo。儘管看起來不是什麼大問題,但是如果有成千上萬行程式碼時,這將是個難以追蹤的 bug。

複製程式碼 程式碼如下:

// global scope
var items = [/* some list */];
for(var i = 0; i     subLoop();
}
function subLoop() {
    // scope of subLoop
    for(i = 0; i         // do amazing stuff!
    }
}

上例中,外部的迴圈將會在執行第一次的時候就停止,這是因為 subloop 函數內部的變數 i 將會覆蓋外部的全域變數 i。我們只需要在函數內部加上一個 var 就可以避免這個錯誤,所以我們在定義變數時一定不要忘記加上關鍵字 var。除非我們確實希望對外部的全域變數造成影響。

局部變數

Javascript 中局部變數只可以透過兩個方式產生,一是透過關鍵字 var 來聲明,一是作為函數的形參。

複製程式碼 程式碼如下:

// global scope
var foo = 1;
var bar = 2;
var i = 2;
function test(i) {
    // local scope of the function test
    i = 5;
    var foo = 3;
    bar = 4;
}
test(10);

此時,函數 test 內部的變數 i 和 foo 是局部變量,而 bar 則會覆寫外部的全域變數 bar。

提升(Hoisting)

Javascript 將會提升變數聲明,這表示 var 表達式和函數宣告都會被提升到作用域的頂端。

複製程式碼 程式碼如下:

bar();
var bar = function() {};
var someValue = 42;
test();
function test(data) {
    if (false) {
        goo = 1;
    } else {
        var goo = 2;
    }
    for(var i = 0; i         var e = data[i];
    }
}

上面的程式碼在運行之前, var 表達式和函數 test 的宣告都會提升至頂部,因此程式將正常運作並不會報錯。

複製程式碼 程式碼如下:

// var statements got moved here
var bar, someValue; // default to 'undefined'
// the function declaration got moved up too
function test(data) {
    var goo, i, e; // missing block scope moves these here
    if (false) {
        goo = 1;
    } else {
        goo = 2;
    }
    for(i = 0; i         e = data[i];
    }
}
bar(); // fails with a TypeError since bar is still 'undefined'
someValue = 42; // assignments are not affected by hoisting
bar = function() {};
test();

由於 Javascript 沒有區塊級作用域,這不僅會提升 var 表達式,同時也會讓 if 結構變得不夠直覺。
在上例中,儘管看起來 if 在對全域變數 goo 進行操作,實際上,由於變數 goo 被提升,所以修改的是局部變數。
如果沒有對提升規則有所了解,你可能會認為下面的程式碼將會拋出 ReferenceError 錯誤。

複製程式碼 程式碼如下:

// check whether SomeImportantThing has been initialized
if (!SomeImportantThing) {
    var SomeImportantThing = {};
}

當然上面的程式碼是沒有錯誤的,因為在程式碼在運行之前,var 表達式已經被提升到頂部。

複製程式碼 程式碼如下:

var SomeImportantThing;
// other code might initialize SomeImportantThing here, or not
// make sure it's there
if (!SomeImportantThing) {
    SomeImportantThing = {};
}

這裡要推薦下 @nightire 凡哥的博文 《理解 JavaScript(二)》,裡面對提升的講解非常透徹。
名稱解析順序

當嘗試在一個函數作用域內存取一個 foo 變數時,Javascript 將會依照下面的順序來尋找:

目前作用域內是否有 var foo 的定義。
函數形參中是否有 foo 變數。
函數本身的名稱是否為 foo。
跳到外層定義域,再從第一部開始找起。
命名空間

一個最常見的問題就是命名衝突,這是因為 Javascript 只有一個全域作用域所帶來的。但這個問題可以透過匿名的外部函數來解決。

複製程式碼 程式碼如下:

(function() {
    // a self contained "namespace"
    window.foo = function() {
        // an exposed closure
    };
})(); // execute the function immediately

上例中的匿名函數被認為是表達式,所以它們會被執行。

複製程式碼 程式碼如下:

( // evaluate the function inside the parentheses
function() {}
) // and return the function object
() // call the result of the evaluation

當然我們也可以用其他方式來呼叫函數表達式,不同的結構,但是同樣的效果。

複製程式碼 程式碼如下:

// A few other styles for directly invoking the
!function(){}()
function(){}()
(function(){}());
// and so on...

總結

建議大家使用匿名的外部函數來將程式碼封裝到空間內,這樣不僅可以解決命名空間的衝突,同時也有利於程式的模組化。
此外,使用全域變數不是一個好習慣,這將帶來高成本的維護代價而且容易產生錯誤。

命名空間同型、函數、變數、範本等都屬於實體(entity)。
實體的主要的共通性是,可以具有名稱。 (此外,標籤也可以有名稱,但它不是實體。)
而命名空間作用域是作用域中的一類統稱,和區塊作用域、類別作用域、函數原型作用域、函數作用域(僅對標籤有效)並列。命名空間內聲明的名稱在命名空間作用域中。全域名稱被認為在隱含的全域命名空間作用域中。

命名空間作用確實就是作用域,但是,他又不同於簡單的作用域,你可以分多次在多處聲明同一個命名空間,但是裡面的內容不能重定義,他們最終都會合成一個命名空間,就像std,到處宏定義

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

See all articles

熱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

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

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。