javascript --- 再讀作用域和閉包

執行環境:

// 定義了變量或函數有權訪問的其他數據,決定了它們各自的行為
// 每個執行環境都有一個與之關聯的變量對象
// 執行環境中定義的所有變量和函數都保存在這個變量中

執行環境與函數:

// 每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中.
// 而在函數執行之后,棧將其環境彈出,把控制權返回給之前的執行環境

作用域鏈:

// 當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈.
// 作用域鏈的用途:保證對執行環境有權訪問的所有變量和函數的有序訪問
// 作用域鏈的前端,始終是當前執行的代碼所在環境的變量對象
// 如果這個環境是函數,則將其活動對象作為變量對象.
// 活動對象在最開始時只包含一個變量,即arguments對象.
// 作用域鏈中的下一個變量對象來自包含環境
// 再下一個變量對象來自下一個包含環境
// ...
// 一直延續到全局執行環境!

理解作用域鏈:

// 當某個函數被調用時,會創建一個執行環境(execution context)及相應的作用域鏈
// 然后,使用arguments和其他命名參數的值來初始化函數的活動對象
// 在作用域鏈中,外部函數的活動對象始終處于第二位
// 外部函數的外部函數的活動對象處于第三位
// ...
// 直至作用域鏈終點的全局執行環境
// 一個例子
function compare(value1, value2) {if (value1 < value2) {return -1;} else if (value1 > value2) {return 1;} else {return 0;}
}
var result = compare(5, 10);// 當在全局環境中調用compare()時,會創建一個活動對象(包含arguments、value1、value2)
// 作用域鏈中的第一位是compare()的活動對象:arguments、value1、value2
// 作用域鏈中的第位則是全局變量對象:compare、result

在這里插入圖片描述

// 后臺的每個執行環境都有一個表示變量的對象 --- 變量對象
// 全局環境的變量對象始終存在
// 函數的局部環境變量,只在函數執行的過程中存在.
// 創建compare()函數時,會創建一個預先包含全局變量對象的作用域鏈,這個作用域鏈保存在內部的[[Scope]]屬性中
// 當調用compare()函數時,會為函數創建一個執行環境,然后通過復制函數的[[Scope]]屬性中的對象構建起執行環境的作用域鏈
// 然后將活動對象(arguments、value1、value2)推入執行環境作用域鏈的前端.// 一般來講,當函數執行完畢后,局部活動對象就會被銷毀,內存中僅保存全局作用域.

閉包:

// 有權訪問另一個函數作用域的變量的函數
// 閉包的常見方式,就是在一個函數內部創建另一個函數
// 閉包的情況有所不同
// 在另一個函數內部定義的函數會將 外部函數的活動對象添加到它的作用域鏈中
function createComparisonFunction(propertyName) {return function(object1, object2) {var value1 = object1[propertyNmae];var value2 = object2[propertyNmae];if( value1 < value2 ) {return -1;} else if ( value1 > value2 ) {return 1;} else {return 0;}};
}
// 在createComparisonFunction()函數內部定義的匿名函數(function(value1,value2))的作用域鏈中
// 實際上將會包含外部函數createComparionFunction()的活動對象
// 在匿名函數從createComparionaFuncion()中被返回后,它的作用域鏈被初始化為包含
// createComparionFunction()函數的活動對象和全局變量對象
// 這樣,匿名函數就可以訪問在createComparionFunction()中定義的所有變量.
// 更重要的是,createComparionFunction()函數在執行完畢后,其活動對象不會被銷毀,因為匿名函數的作用域鏈仍然在引用這個活動對象

在這里插入圖片描述
參考《JavaScript高級程序設計》(第3版)P73~P74、 P178~P180

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

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

相關文章

DOM-15/16【實戰】鼠標行為預測技術

鼠標預測行為動作復雜&#xff0c;使用事件代理得不償失&#xff0c;在數量有限的情況下&#xff0c;使用循環綁定更好用戶從menu斜著向右下角滑入時&#xff0c;可能是進入main&#xff0c;也可能是要選擇子菜單&#xff0c;在判斷前先做延遲如何判斷用戶進入main的意圖&#…

SQLMAP命令詳解

1.基礎信息 python sqlmap/sqlmap.py -u "http://url/news?id1" --current-user #獲取當前用戶名稱 python sqlmap/sqlmap.py -u "http://www.xxoo.com/news?id1" --current-db #獲取當前數據庫名稱 python sqlmap/sqlmap.py -u "http://www.xxoo.…

Nginx命令大全

sudo nginx #打開 nginx nginx -s reload|reopen|stop|quit #重新加載配置|重啟|停止|退出 nginx nginx -t #測試配置是否有語法錯誤nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]-?,-h : 打開幫助信息 -v : 顯示版本信…

ES6-1 ES6版本過渡歷史

一 歷史 HTML HTML 1, HTML 2, HTML 3 1991-1997 IETF(the Internet Engineering Task Force) 國際互聯網工程任務組1997.1 HTML3.2 W3C JavaScript 1995 liveScript(后改名為JavaScript1996年改名)1996 javascript 1.0 1.1;1997 Jscript1997.6 ECMAScript 1.01998.6 ECMAS…

oracle 數據庫查詢 COALESCE字符函數

功能&#xff1a;返回其參數中的第一個非空表達式&#xff0c;當你要在n個字段中選取某一個非空值 coalesce函數返回參數&#xff08;列名&#xff09;中第一個非NULL的字段值&#xff0c;注意不是為空 select COALESCE(t1.a ,t2.a) as a from table_a t1left join table_b t2…

Django-model進階

知識預覽 QuerySet中介模型查詢優化extra整體插入回到頂部QuerySet 可切片 使用Python 的切片語法來限制查詢集記錄的數目 。它等同于SQL 的LIMIT 和OFFSET 子句。 1>>> Entry.objects.all()[:5] # (LIMIT 5)>>> Entry.objects.all()[5:10] # (OFFSE…

vue --- 修飾符.lazy、.number、.trim

.lazy: 會在轉變為change事件中同步 <div id"app"><input type"text" v-model.lazy"message"><p>{{ message }}</p> </div> <script>const app new Vue({el:#app,data: {message: }}) </script> //…

ES6-2 塊級作用域與嵌套、let、暫行性死區

注意&#xff0c;寫在開頭 function test(x 1) {var x // 不報錯console.log(x) } function test1(x 1) {let x 10 // 報錯console.log(x) }let的變量名不可以和參數中的名稱相同。而var并不限制&#xff0c;說白了就是希望你規范使用變量名。 形參原則上數組函數內部的臨…

常用的操作系統知識

為什么要有操作系統 現代計算機系統是由一個或者多個處理器&#xff0c;主存&#xff0c;磁盤&#xff0c;打印機&#xff0c;鍵盤&#xff0c;鼠標顯示器&#xff0c;網絡接口以及各種其他輸入&#xff0c;輸出設備組成的復雜系統&#xff0c;每位程序員不可能掌握所有系統實現…

vue --- 使用中央事件總線(bus)實現跨組件通信

使用Bus實現跨組件傳輸須注意以下3點: 1.需要創建一個空的Vue實例(bus),來作為中間站 2.使用bus.emit來發送事件3.使用bus.emit來發送事件 3.使用bus.emit來發送事件3.使用bus.on來監聽事件(在鉤子created中監聽) 代碼如下: <!DOCTYPE html> <html> <head>…

Execution Order of Event Functions, unity 3d 事件函數的執行順序

vs_Community.exe --layout "F:\linson\vs2017 comm\offline" --lang zh-CN 學習unity3d&#xff0c;感覺事件順序很重要。就翻譯一下官方文檔吧。 Execution Order of Event Functions 事件函數的執行順序 In Unity scripting, there are a number of event functio…

ES6-3 let進階、const、全部變量與頂層對象

一 const 1. 定義常量 1.1 引入模塊時 const test require(http)1.2 定義時必須賦值(初始化)且不可修改 const a; // Uncaught SyntaxError: Missing initializer in const declaration若賦值為原始值&#xff0c;不可修改若賦值為引用值&#xff0c;對于的地址不可修改&a…

前后端如何通信

目錄 前后端如何通信URL . URI . URN第一部分&#xff1a;傳輸協議第二部分&#xff1a;域名第三部分&#xff1a;端口號第四部分&#xff1a;請求資源文件的路徑名稱第五部分&#xff1a;問號傳參第六部分&#xff1a;HASH值前后端如何通信 前段&#xff1a;客戶端 后端&#…

vue --- 獲取子組件數據的一個應急方案$refs

使用$refs需要注意以下2點: 1.html方法使用子組件時,需使用ref “xxx” 聲明. 2.在父組件中使用,this.refs.xxx.msg 獲取數據 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> </head> <body><div id"app"…

Mysql 根據出生日期計算年齡

最近因為業務要求需要根據出生日期計算年齡&#xff0c;在網上查了好多的方法&#xff0c;在這里總結一下。 網上的計算方法好多都提到了格里高利歷法&#xff0c;特意去查了下資料&#xff0c;普及點知識。 格里高利歷是公歷的標準名稱&#xff0c;是一種源自于西方社會的歷法…

ES6-4/5 解構賦值、函數默認值、數組解構、對象解構

ES-4 解構賦值、函數默認值、數組解構、對象解構 ES-5 隱式轉換、函數參數解構、解構本質、()用法 一 解構賦值 1 虛值 含義&#xff1a;在Boolean轉換結果為假的值falsy 2 函數默認值 ES6 內部使用嚴格相等運算符&#xff08;&#xff09;&#xff0c;判斷一個位置是否有值…

springboot之session、cookie

1- 獲取session的方案 session: https://blog.csdn.net/yiifaa/article/details/77542208 2- session什么時候創建&#xff1f; 一個常見的誤解是以為session在有客戶端訪問時就被創建&#xff0c;然而事實是直到某server端程序調用HttpServletRequest.getSession(true)這樣…

echarts --- 多折線圖按段顯示顏色規則訂制

描述: 圖中有4個序列,序列1和序列2在同一個x軸下,顯示不同的顏色.(如,在-40到-30,序列一是紅色,而序列2是黑色) 關鍵: VisualMap中的seriesIndex屬性(根據不同的系列,制定不同的顏色規則). 下面是代碼,可以直接復制到 echart實例 中進行調試 var symbolSize 20; var data [[…

Git-分布式版本控制系統

一、版本控制 版本控制系統是記錄若干文件內容變化&#xff0c;以便將來查閱修訂特定版本或還原部分文件的系統 分為&#xff1a;集中式版本控制系統&#xff08;svn&#xff09;簡稱cvcs 都有一個單一集中管理服務器&#xff0c;保存所有文件修訂版本&#xff0c;開發人員通…

ES6-6 - this指向、箭頭函數基本形式、rest運算符

一 chrome斷點調試 觀察函數調用棧 // 25min var x 1; function foo(x, y function () { x 2; console.log(2) }) {var x 3;y();console.log(x) } foo() console.log(x) // 2 3 1var x 1; function foo(x, y function () { x 2; console.log(x) }) {x 3;y();console.…