JavaScript 作用域、命名空間及閉包

来源:https://www.cnblogs.com/lemonyam/archive/2019/04/07/10659286.html
-Advertisement-
Play Games

變數作用域: 1、一個變數的作用域是程式源代碼中定義這個變數的區域 2、在函數內聲明的變數是局部變數,它只在該函數及其嵌套作用域里可見(js 函數可嵌套定義);不在任何函數內聲明或在函數內不使用 var 或 let 關鍵字聲明的變數是全局變數,它在整個 JavaScript 程式里都可見 3、Jav ...


變數作用域:

  1、一個變數的作用域是程式源代碼中定義這個變數的區域

  2、在函數內聲明的變數是局部變數,它只在該函數及其嵌套作用域里可見(js 函數可嵌套定義);不在任何函數內聲明或在函數內不使用 var 或 let 關鍵字聲明的變數是全局變數,它在整個 JavaScript 程式里都可見

  3、JavaScript 中沒有塊級作用域,取而代之的是函數作用域

  4、局部變數會遮蓋全局變數

  5、註意變數的聲明提前,即所有變數都會把聲明提前到它的作用域頂端

  6、若使用 let 聲明變數,則該變數只屬於就近的花括弧括起來的語句塊!!!

let test = "global";
function fun() {
    let test = "local";
    // 若改成 test = "local"; 則會修改全局變數 test
    console.log("inFun: ", test);
}
fun();  // 輸出 local
console.log("outFun: ", test);  // 輸出 global


var j = 10; // 由於聲明提前,所以函數內的 j != 10
function check() {
    var i = 0;
    // 因為函數作用域,所以會出現聲明提前的現象(let 聲明除外),即變數聲明之前就可以使用,但其值為 undefined
    console.log("j = ", j);
    for (var j = 0; j < 5; ++j)
        i++;
    console.log("i = ", i, "j = ", j);
}
check();    // 輸出 j = undefined i = 5   j = 5

 

命名空間:

   一般情況下,在 JavaScript 中是無法聲明只在一個代碼塊內可見的變數(let 可以聲明),基於這個原因,我們常常會簡單地定義一個函數用作臨時的命名空間

// function 前面的左圓括弧是必須的,若省略則會將關鍵字 function 解析為函數聲明語句,
// 而不是正確地解析為函數定義表達式
var sum = (function () {
    var a = 2, b = 3;   // 在這裡面定義的變數無法從外面訪問,所以不會污染全局命名空間
    return a + b;
}());   // 後面的圓括弧表示結束函數定義並立即調用它
console.log(sum);   // 輸出 5

 

作用域鏈:

  如果將一個局部變數看作是自定義實現的對象的屬性的話,每一段 JavaScript 代碼(全局代碼或函數)都有一個與之相關的作用域鏈。這個作用域鏈是一個對象列表或鏈表,定義了這段代碼“作用域中” 的變數。當 JavaScript 需要查找某個變數時,它會從鏈中的第一個對象開始查找,若未找到,則查找下一個對象,以此類推。如果作用域鏈上沒有任何一個對象符合查找內容,則會拋出一個引用錯誤異常。

let global = "globalOne";
function f() {
    let global = "globalTwo";
    function f1() {
        let global = "globalThree";
    }
}
/*
   在這段代碼里 global 的值在作用域鏈里為:globalThree -> globalTwo -> globalOne, 
   若查詢代碼在 f1 里,則會從 globalThree 開始尋找,若在 f 里,則從 globalTwo 開始尋找
   若找不到,則往箭頭方向繼續尋找下去,箭頭反方向對它是不可見的
*/

 

閉包:

   函數對象可以通過作用域鏈相互關聯起來,函數體內部的變數都可以保存在函數作用域內,這種特性在電腦科學文獻中被稱為“閉包”。從技術角度講,所有的 JavaScript 函數都是閉包

var counter = (function () {
    var count = 0;
    return function () {
        return ++count;
    };
}());   // 自我調用函數只執行一次。設置計數器為 0。並返回函數表達式。
console.log(counter()); // 輸出 1
console.log(counter()); // 輸出 2
console.log(counter()); // 輸出 3

 註:命名空間通常也是一個函數

// 同一個作用域鏈內定義的閉包會共用同樣的私有變數或變數
// 以下代碼生成 10 個閉包,所有閉包共用變數 i
function constfuncs() {
    var funcs = [];
    for (var i = 0; i < 10; ++i)
        funcs[i] = function () {
            return i;   // 嵌套函數不會將作用域內的私有成員複製一份,也不會對所綁定的變數生成靜態快照
        };
    return funcs;
}
var funcs = constfuncs();   // 當 constfuncs 返回時 i = 10
console.log(funcs[5]());    // 輸出 10

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、我在打包完成後,打開index.html文件發現地址並沒有攜帶路由。 config下的 index.js 中的build命令的配置有一個屬性叫assetsPublicPath,它的值為‘/’。意思是根目錄,這時會從index.html所在的硬碟的根目錄下開始查找,自然無法找到。 解決辦法: 改為 ...
  • 最近感覺canvas挺有意思的,在業餘時間沒事研究了一下,參考過網上一些思路,話不多說,開始啦。 github地址:https://github.com/aWhiteBear/fireworks 演示地址:https://awhitebear.github.io/fireworks/ 圖片效果如下: ...
  • 效果圖: ...
  • 1創建連接池對象 2導出連接池對象 1 /** 2 * 1.引入mysql模塊 3 * 2.創建連接池對象 4 * 3.導出連接池對象 5 */ 6 const mysql = require('mysql'); 7 var pool = mysql.createPool({ 8 host:'loc ...
  • 實現輸入內容點擊請留言按鈕,就會在下方留言並且後面有刪除選項,點擊即可刪除留言。 ...
  • 測試代碼: ...
  • 實例代碼: 同理可應用在超鏈接、按鈕等中 ...
  • typeof操作符返回一個字元串,表示未經計算的操作數的類型。 可能返回值有:"undefined"、"object"、"boolean"、"number"、"string"、"symbol"、"function"、"object" 例: instanceof運算符用於測試構造函數的prototyp ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...