javascript 之作用域鏈-07

来源:http://www.cnblogs.com/CandyManPing/archive/2017/11/01/7764664.html
-Advertisement-
Play Games

複習作用域 上一節我們說到作用域:是指變數可以訪問的範圍,他規定瞭如何查找變數,以及確定當前執行代碼對變數的訪問許可權;也說到靜態作用域即詞法作用域,是在編譯階段決定變數的引用(由程式定義的位置決定,和代碼執行順序無關,用嵌套的方式解析)。 凝問 如上代碼,在執行run函數時,在run作用域中有nam ...


複習作用域

上一節我們說到作用域:是指變數可以訪問的範圍,他規定瞭如何查找變數,以及確定當前執行代碼對變數的訪問許可權;也說到靜態作用域即詞法作用域,是在編譯階段決定變數的引用(由程式定義的位置決定,和代碼執行順序無關,用嵌套的方式解析)。

疑問

1     var x=10;
2     function run(){
3         var name='Joel';
4         console.log(x+name);//10Joel  這裡做了隱適轉換 當有+時有一個為string 那麼會當做字元拼接來處理
5     }
6     run();

如上代碼,在執行run函數時,在run作用域中有name變數,但是並沒有變數x,那麼為什麼不會報錯,變數x又是怎麼訪問的呢?可能有些人理解是去父級函數作用域中尋找變數,其實這樣理解作用域存在歧義(如果理解為是在調用函數的父級函數,那麼肯定是錯的  如下代碼),上一節我們說過javascript的作用域是靜態作用域,即應該關心代碼定義的位置而不是調用的位置 (詞法作用域);

 1     var x=10;
 2     function fn(){
 3         console.log(x);
 4     }
 5     function show(f){
 6         var x=20;
 7         (function(){
 8             f()
 9         }());
10     }
11     show(fn);//10 並不是20

引出作用域鏈

通過分析作用域的變數解析來理解作用域鏈

 1  var a=10;
 2     function run(){
 3         var name='Joel';
 4         function say(){
 5             var content='hello';
 6             console.log(content+name+','+a);
 7         }
 8         say();
 9     }
10     run();//helloJoel,10

通過上一篇我們知道js作用域有全局作用域,函數作用域,所以上面代碼作用域如下:

全局作用域:存在變數a、run函數引用,當然還存在其他函數、屬性(內置的就不討論了);

run函數作用域:存在變數 name 、say函數引用;

say函數作用域:存在變數content;

當代碼執行到 console.log(content+name+','+a); 首先在say函數作用域中尋找變數content、name、a,如果找到則停止,沒有找到就到上一個作用域中尋找,以此類推一直到window 全局作用域,如變數a 在當前say 作用域中沒有,就到run作用域中尋找,還沒找到就到全局作用域中尋找,如果還找不到就報錯 is not defined,因為全局作用域是最外層作用域 ;

繼續看下麵代碼,我們在say函數中定義了變數name 之後,name值不在是run作用域中的值,因為在say作用域中找到了變數name 就不會繼續尋找了

 1 <script>
 2     var a=10;
 3     function run(){
 4         var name='Joel';
 5         function say(){
 6             var content='hello',name=' Word';
 7 
 8             console.log(content+name+','+a);
 9         }
10         say();
11     }
12     run();//hello Word,10
13 </script>

這樣一步一步的尋找變數的過程我們叫做標識符解析或者你可以理解為變數解析,那麼提供這個線路或者這樣尋找變數的機制我們叫做作用域鏈;

我們來總結一下這個過程:

第一步,在當前作用域查找變數,如果有則獲取並停止。如果沒有則繼續向上一個作用域尋找;

第二步,如果當前作用域是全局作用域,則說明變數未定義,結束;否則繼續;

第三步,(不是全局作用域,那就是函數作用域)繼續第一步;

那麼作用域鏈到底是什麼呢?

其實作用域鏈本質是一個指向變數對象的指針鏈表,它只引用但不實際包含變數對象的值;

如上代碼作用域鏈結構類似這樣:

這篇只是引出作用域鏈,下一篇正式開始說執行環境,會涉及到變數對象、活動對象、作用域鏈等內容從而深入作用域鏈的創建過程。

之所以要先寫執行環境,是因為完整的作用域鏈是在執行環境中構建的。


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

-Advertisement-
Play Games
更多相關文章
  • 平時在寫的代碼過程中,經常會遇到對對象Object的數據處理。而在對對象的數據處理中,操作最頻繁的是“數據引用”、“值的修改”、“獲取關鍵字(屬性)”。平時最煩的也是“獲取關鍵字”,經常忘記怎麼去獲取,這裡做一下整理。 既然要"獲取關鍵字",那麼得首先有一個對象才行。創建對象的方式很多,我自己慣用的 ...
  • 一般我發現slot都是用在子組件 不知道對不對,不對的請留言指教 ,謝謝謝謝 使用slot場景一: 子組件Minput.vue 父組件 Minput 這種情況下 Minput標簽內的文字是不會渲染出來的 如果現在想在裡面把文字渲染出來怎麼辦 好 用slot 子組件 這樣的話,父組件的裡面的文字就可以 ...
  • 今天在調試bug的時候有一個需求,我需要知道我的代碼中有哪些地方在修改body的style,然後我想到了DOM節點監聽。 為body添加斷點然後開始調試,但是現在的前端技術棧太複雜,即使打了斷點也會跳進第三方包里。調用棧里有太多無關的js代碼,妨礙調試。 所以你可以選中文件右擊後,選擇Blackbo ...
  • 在開發的過程中,幾乎不可能一次性就能寫出毫無破綻的程式,斷點調試代碼是一個普遍的需求。 作為前端開發工程師,以往我們開發的JavaScript程式都運行在瀏覽器端,利用Chrome提供的開發者工具就可以方便的進行源碼斷點調試。其步驟有四,詳情不表,粗略概括如下: 但是,當我們用JavaScript開 ...
  • 控制項概述 Google Maps 上的地圖包含用戶界面元素,可以讓用戶通過地圖進行交互。這些元素稱為“控制項”。您可以在 Google Maps API 應用程式中添加這些控制項的多種組合。或者,您也可以不進行任何操作,讓 Google Maps API 處理所有控制項行為。 Google Maps AP ...
  • /** 日期格式化 */Date.prototype.Format = function(format) { var o = { "M+" : this.getMonth() + 1, // month "d+" : this.getDate(), // day "H+" : this.getHou ...
  • z 品牌:騰訊案例地址:http://www.199case.com/caseview.aspx?id=624 來源:199case_H5案例庫 1、內容:通過首頁的js動態按鈕進入下一界面,整個過程橫屏設置,採用了拍攝好的完整多骨諾視頻,並且在視頻的不同節點出現相應文字,可以鮮明和充分的展現TEG ...
  • 品牌:保時捷 案例地址:http://www.199case.com/caseview.aspx?id=2875 來源:199case-H5案例庫 1、內容:一個以”捕捉迅疾魅影“為主題的聲音識別類的h5,用戶可以通過聽取最大的跑車的引擎聲,然後點擊相機狀的按鈕,即可拍攝成功,最後展示類保時捷的跑車 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...