JavaScript篇:函數作用域與作用域鏈探秘

大家好,我是江城開朗的豌豆,一名擁有6年以上前端開發經驗的工程師。我精通HTML、CSS、JavaScript等基礎前端技術,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能夠高效解決各類前端開發問題。在我的技術棧中,除了常見的前端開發技術,我還擅長3D開發,熟練使用Three.js進行3D圖形繪制,并在虛擬現實與數字孿生技術上積累了豐富的經驗,特別是在虛幻引擎開發方面,有著深入的理解和實踐。

? ? ? ? 我一直認為技術的不斷探索和實踐是進步的源泉,近年來,我深入研究大數據算法的應用與發展,尤其在數據可視化和交互體驗方面,取得了顯著的成果。我也注重與團隊的合作,能夠有效地推動項目的進展和優化開發流程。現在,我擔任全棧工程師,擁有CSDN博客專家認證及阿里云專家博主稱號,希望通過分享我的技術心得與經驗,幫助更多人提升自己的技術水平,成為更優秀的開發者。

目錄

函數作用域:你的私人領地

塊級作用域的小插曲

作用域鏈:尋寶地圖

閉包:作用域鏈的魔法應用

常見誤區與陷阱

1. 變量提升的坑

2. 循環中的閉包問題

最佳實踐建議

總結:掌握你的"秘密基地"


作為前端開發者,我們每天都在和JavaScript的各種概念打交道。今天我要帶大家探索JavaScript中兩個看似神秘實則有趣的概念——函數作用域和作用域鏈。它們就像是代碼世界里的"秘密基地",理解它們能讓你寫出更安全、更高效的代碼。

函數作用域:你的私人領地

想象一下,函數就像是你自己的房間,而函數作用域就是這個房間的圍墻。在房間里(函數內部)聲明的變量,就像是你的私人物品,外人(函數外部)是看不到也摸不著的。

function mySecretRoom() {const myDiary = "我今天學會了函數作用域";console.log(myDiary); // 可以訪問
}mySecretRoom(); // 輸出: "我今天學會了函數作用域"
console.log(myDiary); // 報錯: myDiary is not defined

在這個例子里,myDiary就像是放在我房間里的日記本,只有在房間內(函數內部)才能查看。一旦出了房間(函數外部),別人就找不到這本日記了。

塊級作用域的小插曲

ES6引入了letconst后,JavaScript也有了塊級作用域(用{}包裹的代碼塊):

if (true) {const myToy = "樂高積木";console.log(myToy); // 可以訪問
}
console.log(myToy); // 報錯: myToy is not defined

這里myToy就像是我在游樂場臨時買的玩具,離開游樂場(代碼塊)后就找不到了。

作用域鏈:尋寶地圖

現在我們來聊聊更有趣的作用域鏈。想象你正在玩一個尋寶游戲,作用域鏈就是你的尋寶地圖,告訴你在哪里可以找到需要的"寶物"(變量)。

const globalTreasure = "我是全局寶藏";function outerFunction() {const outerTreasure = "我是外層寶藏";function innerFunction() {const innerTreasure = "我是內層寶藏";console.log(`我找到了: ${innerTreasure}`); // 先找最近的console.log(`我找到了: ${outerTreasure}`); // 然后找上一層的console.log(`我找到了: ${globalTreasure}`); // 最后找全局的}innerFunction();
}outerFunction();

JavaScript查找變量的順序就像這樣:

  1. 先在當前作用域找(我的口袋)

  2. 找不到就去外層作用域找(我的房間)

  3. 還找不到就去更外層找(我的家)

  4. 最后去全局作用域找(小區公共區域)

如果到最后都沒找到,就會報錯:"寶物不存在"(變量未定義)。

閉包:作用域鏈的魔法應用

理解了作用域鏈,閉包就很好解釋了。閉包就像是把你的"秘密基地"打包帶走的能力。

function createCounter() {let mySecretCount = 0;return function() {mySecretCount++;console.log(`我偷偷數到: ${mySecretCount}`);};
}const counter = createCounter();
counter(); // 我偷偷數到: 1
counter(); // 我偷偷數到: 2

這里mySecretCount本該在createCounter執行完后就消失,但因為返回的函數還在引用它,JavaScript就會把它"打包"保存下來,這就是閉包的魔力。

常見誤區與陷阱

1. 變量提升的坑

console.log(myBook); // undefined,而不是報錯
var myBook = "JavaScript高級程序設計";

var聲明的變量會提升到函數頂部,但賦值不會。這就像是你先告訴大家"我有本書",但書還沒拿出來給大家看。

2. 循環中的閉包問題

for (var i = 0; i < 3; i++) {setTimeout(function() {console.log(`我現在的i是: ${i}`);}, 100);
}
// 輸出三個: "我現在的i是: 3"

這是因為var沒有塊級作用域,所有回調函數共享同一個i。改用let就能解決:

for (let i = 0; i < 3; i++) {setTimeout(function() {console.log(`我現在的i是: ${i}`);}, 100);
}
// 輸出: "我現在的i是: 0", "我現在的i是: 1", "我現在的i是: 2"

最佳實踐建議

  1. 盡量使用constlet:避免var的變量提升和函數作用域帶來的困惑

  2. 避免污染全局作用域:把你的"寶物"盡量放在"房間"里,而不是"公共區域"

  3. 合理使用閉包:閉包很強大,但濫用會導致內存泄漏

  4. 保持作用域清晰:過深的嵌套會讓代碼難以理解

總結:掌握你的"秘密基地"

  • 函數作用域:是你的私人領地,保護變量不被外界干擾

  • 作用域鏈:是你的尋寶地圖,指導JavaScript如何查找變量

  • 閉包:是打包帶走你的"秘密基地"的超能力

理解這些概念后,你就能更好地組織代碼,避免變量沖突,寫出更安全、更易維護的JavaScript代碼。下次當你寫函數時,不妨想象你正在建造自己的"秘密基地",思考每個變量應該放在哪個位置最合適。

記住,好的開發者不僅是寫代碼的人,更是代碼世界的建筑師!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80962.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80962.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80962.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Robust Kernel Estimation with Outliers Handling for Image Deblurring論文閱讀

Robust Kernel Estimation with Outliers Handling for Image Deblurring 1. 論文的研究目標與實際問題意義1.1 研究目標1.2 實際問題與產業意義2. 論文的創新方法、模型與優勢2.1 核心思路2.2 關鍵公式與技術細節2.2.1 非線性模糊模型與能量函數2.2.2 中間潛像更新與IRLS2.2.3…

nginx配置跨域請求,后臺不用配置啦,完美

允許全部把域名改* server { listen 22222; server_name localhost; location / { if ($request_method OPTIONS) { add_header Access-Control-Allow-Origin http://localhost:8080; add_header Access-Control-Allow-Headers *; add_header Access-Control-…

[特殊字符] 構建高內聚低耦合的接口架構:從數據校驗到后置通知的分層實踐

在現代企業系統開發中&#xff0c;接口結構設計的質量直接影響系統的穩定性、擴展性與可維護性。隨著業務復雜度上升&#xff0c;單一層次的接口實現往往難以應對功能膨脹、事務一致性、后置擴展等需求。因此&#xff0c;我們提出一種面向復雜業務場景的接口分層模型&#xff0…

MySQL 5.7 實戰:JSON 字段提取、Base64 解碼與引號問題全解析

一、背景與問題場景 在 MySQL 數據庫中&#xff0c;存儲 JSON 格式數據&#xff08;如用戶行為日志、配置參數、擴展信息&#xff09;的場景日益普遍。當需要從 JSON 字段中提取特定鍵值&#xff08;如info&#xff09;并進行 Base64 解碼時&#xff0c;常遇到以下問題&#x…

1.2.1+1.2.2計算機硬件的基本組成

知識總覽 早期馮諾依曼計算機&#xff1a;從人工-》自動 出現原因&#xff1a; 埃尼阿克計算機每執行一條指令都需要人工接線攬&#xff0c;雖然計算機處理的快&#xff0c;但是人工接線可能慢&#xff0c;效率低&#xff0c;于是出現馮諾依曼計算機&#xff0c;把要執行的指…

Spring AI 1.0 GA 正式發布

Spring AI 1.0 GA 正式發布 快速入門核心特性1. **增強型 LLM&#xff08;大語言模型&#xff09;**2. **MCP 協議支持**3. **RAG&#xff08;檢索增強生成&#xff09;**4. **評估與監控**5. **智能代理&#xff08;Agents&#xff09;** 下一步計劃 VMware Spring 團隊 Mark …

亞馬遜云科技推出Anthropic新一代模型

5月23日 亞馬遜云科技宣布在Amazon Bedrock中推出Anthropic的最新一代模型Claude Opus 4和Claude Sonnet 4。這兩款全新混合推理模型能夠根據需求在快速響應和深度思考模式間靈活切換&#xff0c;為編碼、高級推理和多步驟工作流領域帶來全新標準。它們不僅能在復雜的長時間推理…

無人機開啟未來配送新篇章

低空物流&#xff08;無人機物流&#xff09;是利用無人機等低空飛行器進行貨物運輸的物流方式&#xff0c;依托低空空域&#xff08;通常在120-300米&#xff09;實現快速、高效、靈活的配送服務。它是低空經濟的重要組成部分&#xff0c;廣泛應用于快遞配送、醫療物資運輸、農…

數據賦能(234)——數據管理——標準化原則

概述 標準化原則的重要性體現在確保數據的格式、結構和命名的一致性。這不僅可以提高數據的質量&#xff0c;還能促進數據的有效共享、交換和利用。以下是標準化原則的重要性的具體體現&#xff1a; 提高數據通用性&#xff1a;遵循數據標準和規范&#xff0c;確保不同系統、…

【Linux筆記】——線程池項目與線程安全單例模式

&#x1f525;個人主頁&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收錄專欄&#x1f308;&#xff1a;Linux &#x1f339;往期回顧&#x1f339;&#xff1a; 【Linux筆記】——簡單實習一個日志項目 &#x1f516;流水不爭&#xff0c;爭的是滔滔不息 一、線程池設計二…

28-FreeRTOS內核控制-延時-臨界區

一、FreeRTOS的內核控制接口分析 1.1 函數taskYIELD 此函數用于進行任務切換&#xff0c;此函數本質上是一個宏。它允許當前任務主動放棄CPU使用權&#xff0c;將控制權轉移給調度器&#xff0c;以便調度器可以選擇另一個就緒任務運行。taskYIELD通常用于協作式多任務系統中&am…

NtfsLookupAttributeByName函數分析之和Scb->AttributeName的關系

第一部分&#xff1a; VOID FindFirstIndexEntry ( IN PIRP_CONTEXT IrpContext, IN PSCB Scb, IN PVOID Value, IN OUT PINDEX_CONTEXT IndexContext ) { 。。。。。。 // // Lookup the attribute record from the Scb. // if (!NtfsLookupAt…

關閉 Ubuntu 20.04 的 GNOME Shell和PulseAudio

一、GNOME Shell GNOME Shell 是 Ubuntu 20.04 默認的桌面環境管理器。關閉它會失去圖形界面&#xff08;回到純終端模式&#xff09;&#xff0c;但可以節省內存和 CPU 資源。 方法 1&#xff1a;臨時關閉&#xff08;當前會話生效&#xff09; sudo systemctl stop gdm #…

Dijkstra算法——不帶負權的單源最短路徑

目錄 算法學習 算法原理 稠密圖Dijkstra模板 稀疏圖Dijkstra模板 練習 1 網絡延遲時間 2 到達最后一個房間的最少時間Ⅰ 3 到達最后一個房間的最少時間Ⅱ 4 訪問消失節點的最少時間 5 設計可以求最短路徑的圖類 6 概率最大的路徑 7 最小體力消耗路徑 8 從第一個節…

【安全攻防與漏洞?】??Heartbleed漏洞復現與修復

Heartbleed漏洞復現與修復 一、漏洞原理 Heartbleed漏洞&#xff08;CVE-2014-0160&#xff09; 是 OpenSSL 1.0.1 至 1.0.1f 版本中的一個嚴重內存泄漏漏洞。它源于 TLS 心跳擴展&#xff08;Heartbeat Extension&#xff09;協議中對請求長度字段的未校驗&#xff0c;導致攻…

力扣-最大連續一的個數

1.題目描述 2.題目鏈接 1004. 最大連續1的個數 III - 力扣&#xff08;LeetCode&#xff09; 3.代碼解答 class Solution {public int longestOnes(int[] nums, int k) {int zero0,length0;for(int left0,right0;right<nums.length;right){if(nums[right]0){zero;}while…

虛擬機Centos7:Cannot find a valid baseurl for repo: base/7/x86_64問題解決

問題 解決&#xff1a;更新yum倉庫源 # 備份現有yum配置文件 sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup# 編輯CentOS-Base.repo文件 vi /etc/yum.repos.d/CentOS-Base.repo[base] nameCentOS-$releasever - Base baseurlhttp://mirrors.aliyun.com/centos/$relea…

Node.js 庫大全

在當今快速迭代的軟件開發領域&#xff0c;Node.js 憑借其強大的異步 I/O 處理能力和繁榮的生態系統&#xff0c;已成為全棧開發的核心技術。社區中涌現的無數實用庫&#xff0c;如同開發者手中的“瑞士軍刀”&#xff0c;能顯著提升效率、優化性能并保障安全。本文將系統梳理 …

如何評估物聯網框架的交互體驗?

物聯網&#xff08;IoT&#xff09;技術的快速發展推動了各類物聯網框架的涌現&#xff0c;但如何評估其交互體驗卻成為開發者和企業面臨的重要挑戰。交互體驗不僅涉及用戶界面&#xff08;UI&#xff09;的直觀性&#xff0c;還包括設備接入效率、協議兼容性、數據交互流暢度以…

3D個人簡歷網站 6.彈出框

3D個人簡歷網站 6.彈出框 在components下創建HomeInfo.jsx用于控制主頁彈出框信息 輸入rafce快速生成代碼塊 import React from reactconst HomeInfo () > {return (<div>HomeInfo</div>) }export default HomeInfo修改Home.jsx代碼實現彈出簡單效果 ……re…