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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...