函數表達書-讀書筆記

定義函數的方式有兩種:一種是函數聲明,另一種就是函數表達式。函數聲明的語法如下:

function functionName(arg0,arg1,arg2){//函數體
}

函數聲明,有一個重要特征就是函數聲明提升。也就是在執行代碼之前會先讀取函數聲明,也就意味著可以把函數聲明放在調用它的語句后面。

sayHi();
function sayHi(){console.log("Hi!");
}

下面介紹函數表達式的語法:

var functionName = function(arg0,arg1,arg2){//函數體  
}

這種看起來好像常規的變量賦值語句,就是創建一個函數并將它賦值給變量functionName,這樣的函數就是匿名函數,注意function關鍵字后面沒有標識符,匿名函數的name屬性是空字符串。

函數表達式和其他表達式一樣,在使用之前必須先賦值。

sayHi(); //錯誤:函數還不存在
var sayHi = function(){alert("Hi!");
};

一、閉包

閉包是指有權訪問另一個函數作用域中的變量的函數。創建閉包的常見方式,就是在一個函數內部創建另一個函數。栗如:

function createComparisonFunction(propertyName) {return function(object1, object2){var value1 = object1[propertyName];var value2 = object2[propertyName];if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}};
}

在函數執行過程中,為讀取和寫入變量的值,需要在作用域鏈中查找變量,栗如:

function compare(value1, value2){if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}
}
var result = compare(5, 10);

上面代碼先定義了compare()函數,然后又在全局作用域調用了它,當調用compare()時,會創建一個包含arguments、value1、value2的活動對象。全局執行環境的變量對象在compare()執行環境的作用域鏈中則處于第二位,如圖:

在另一個函數內部定義的函數會將包含函數(即外部函數)的活動對象添加到它的作用域鏈中。因此,在createComparisonFunction()函數內部定義的匿名函數的作用域鏈中,實際上將會包含外部函數createComparisonFunction()的活動對象。

var compare = createComparisonFunction("name");
var result = compare({ name: "Nicholas" }, { name: "Greg" });

在匿名函數從createComparisonFunction()中被返回后,它的作用域鏈被初始化為包含createComparisonFunction()函數的活動對象和全局變量對象。這樣,匿名函數就可以訪問在createComparisonFunction()中定義的所有變量。更為重要的是,createComparisonFunction()函數在執行完畢后,其活動對象也不會被銷毀,因為匿名函數的作用域鏈仍然在引用這個活動對象。換句話說,當createComparisonFunction()函數返回后,其執行環境的作用域鏈會被銷毀,但它的活動對象仍然會留在內存中;直到匿名函數被銷毀后,createComparisonFunction()的活動對象才會被銷毀。

//創建函數
var compareNames = createComparisonFunction("name");
//調用函數
var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
//解除對匿名函數的引用(以便釋放內存)
compareNames = null;

首先,創建的比較函數被保存在變量compareNames中,通過設置compareNames為null解除該函數的引用,就等于通知垃圾回收機制將其清除。匿名函數的作用域鏈被銷毀,其他作用域(除了全局作用域)也都可以安全地銷毀了。

作用域鏈帶來了一個副作用,閉包只能取得包含函數中任何變量的最后一個值。閉包所保存的是整個變量對象,而不是某個特殊的變量。舉栗:

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result;
}

這個函數會返回一個函數數組,表面上看,似乎每個函數都有自己的索引值,即位置0的函數返回0,位置1的函數返回1,以此類推。但實際上,每個函數都返回10。因為每個函數的作用域鏈中湊保存著createFunctions()函數的活動對象,所以它們引用的都是同一個變量i。當createFunctions()函數返回后,變量i的值是10,此時每個函數都引用著保存變量i的同一個變量對象,所以在每個函數內部i的值都是10。

我們可以通過創建另一個匿名函數強制讓閉包的行為符合預期。

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(num){return function(){return num;};}(i);}return result;
}

重寫了createFunctions()函數后,每個函數就會返回各自不同的索引值了。在這里,我們沒有直接把閉包賦值給數組,而是定義了一個匿名函數,并立即執行該匿名函數的結果賦給數組。這里的匿名函數有一個參數num,也就是最終的函數要返回的值。

在調用每個匿名函數時,我們傳入了變量i。由于函數參數是按值傳遞的,所以就會將變量i的當前值復制給參數num。而在這個匿名函數內部,又創建并返回一個訪問num的閉包。這樣一來,result數組中的每個函數都有自己num變量的一個副本,因此就可以參會各自不同的數值了。

?

參考資料

《javascript高級程序設計(第3版)》第7章 函數表達式

轉載于:https://www.cnblogs.com/winteronlyme/p/6723234.html

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

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

相關文章

vue截取一個字符串_vue 截取字符串

let str abcdef;// 0str str.slice(0);//返回整個字符串 abcdefstr str.substring(0);//返回整個字符串 abcdefstr str.substr(0);//返回整個字符串 abcdef// 使用一個參數str str.slice(2);//截取第二個之后所有的字符 cdefstr str.substring(2);//截取第二個之后所有的…

網絡工程師需要哪些知識_成長工程師可以教給我們哪些工程知識

網絡工程師需要哪些知識I’ve been working as an engineer on the growth team at Airbnb for a couple of months now.我已經在Airbnb的成長團隊擔任工程師幾個月了。 Since I’m in an environment full of passionate developers, I wanted to share some of the good eng…

linux父進程循環,LINUX C 父進程建立多個子進程循環非堵塞回收列子

下面 代碼主要用于復習&#xff0c;留于此點擊(此處)折疊或打開/*************************************************************************> File Name: fork5.c> Author: gaopeng QQ:22389860 all right reserved> Mail: gaopp_200217163.com> Created Time: …

服務器自動運行python_在虛擬主機中安裝了python程序,如何使它在服務器上自動運行?...

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":3,"count":3}]},"card":[{"des":"IP地理位置庫(GeoIP Databases)是對運營商分…

模擬測試

題解&#xff1a; 3道水題。。 1。生活大爆炸版剪刀石頭布 忘記怎么打f[5][5]{}這個了。。 然后發現里面啥都不加也可以 加的話要是{} 2.送禮物 雙向搜 有點卡常數。。 我沒寫dfs 寫了dp求多少&#xff08;好智障啊。。 訪問數組挺慢的所以應該速度差不多。。&#xff09; lowb…

javascript閉包_通過郵寄包裹解釋JavaScript閉包

javascript閉包by Kevin Kononenko凱文科諾年科(Kevin Kononenko) 通過郵寄包裹解釋JavaScript閉包 (JavaScript Closures Explained by Mailing a Package) 如果您以前寄過包裹或信件&#xff0c;那么您可以了解JavaScript中的閉包。 (If you have mailed a package or lette…

linux 加入ad 用ssh,使用samba驗證AD用戶,允許AD用戶登錄到linux

使用samba驗證AD用戶&#xff0c;允許AD用戶登錄到linux2007年06月26日 星期二 14:101、先把samba加入到AD域中2、在smb.conf中添加一行&#xff0c;讓登錄進來的用戶使用bashtemplate shell /bin/bash3、運行authconfig&#xff0c;在驗證中選擇 使用smb和kerberos,winbind驗…

體會日子

體會日子 開通了博客園&#xff0c; 日子要記錄一下。 以后要好好上進了。 posted on 2016-05-01 23:16 體會日子 閱讀(...) 評論(...) 編輯 收藏 轉載于:https://www.cnblogs.com/yukunshi/p/5451485.html

selenium 難定位元素、時間插件

關于frame: 1. 如果網頁存在iframe的話&#xff0c;傳統的定位有時候找不到元素&#xff0c;需要切換frame&#xff1b; # 切換到leftFrame定位“測井設計” driver.switch_to_frame("leftFrame") driver.find_element_by_link_text(u"設計").click() # 切…

python kmeans聚類 對二維坐標點聚類_Kmeans均值聚類算法原理以及Python如何實現

第一步.隨機生成質心由于這是一個無監督學習的算法&#xff0c;因此我們首先在一個二維的坐標軸下隨機給定一堆點&#xff0c;并隨即給定兩個質心&#xff0c;我們這個算法的目的就是將這一堆點根據它們自身的坐標特征分為兩類&#xff0c;因此選取了兩個質心&#xff0c;什么時…

HDU 2544最短路dijkstra模板題

最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 33657 Accepted Submission(s): 14617Problem Description在每年的校賽里&#xff0c;全部進入決賽的同學都會獲得一件非常美麗的t-shirt。可是每當我們…

我為期一個月的GitHub的經驗教訓

by JS由JS 我為期一個月的GitHub的經驗教訓 (Lessons from my month-long GitHub commit streak) “I want to learn JavaScript. Like, really learn it. Like, truly understand it.” — me in November 2016“我想學習JavaScript。 喜歡&#xff0c;真正地學習它。 喜歡&a…

安裝itunes需要管理員身份_ITUNES無法安裝,提示沒有權限如何解決?

展開全部注意機器一定要登陸管理員系統&#xff0c;如果現在不是&#xff0c;可以注62616964757a686964616fe78988e69d8331333365646263銷&#xff0c;切換一下用戶。還有計算機不要有漏洞&#xff0c;如果有的話修復一下。打開開始運行,輸入regedit,點擊確認打開注冊表編輯器,…

vs2012新建項目產生的問題

當用vs新建web項目時遇到 只需下載一個vs2012的更新插件 http://download.microsoft.com/download/A/0/2/A02C37E0-77F7-448A-BD5C-F66AB1F78DBC/VS11-KB3002339.exe 點擊安裝更新即可. 轉載于:https://www.cnblogs.com/GreenLeaves/p/5452073.html

zoj4062 Plants vs. Zombies 二分+模擬(貪心的思維)

題目傳送門 題目大意&#xff1a;有n個植物排成一排&#xff0c;標號為1-n&#xff0c;每株植物有自己的生長速度ai&#xff0c;每對植物澆一次水&#xff0c;該株植物就長高ai&#xff0c;現在機器人從第0個格子出發&#xff0c;每次走一步&#xff0c;不能停留&#xff0c;每…

MyBatis注解模式批量insert方法

2019獨角獸企業重金招聘Python工程師標準>>> 方法一:script標簽方式 Insert("<script>insert into xxx (channelId,siteId) " "values " "<foreach collection\"list\" item\"item\" index\"index\&quo…

尚硅谷學費有住宿么_我在12個小時的住宿期間了解到的硅谷知識

尚硅谷學費有住宿么by Sahil Khoja由Sahil Khoja 我在12個小時的住宿期間了解到的硅谷知識 (What I learned about Silicon Valley during my 12 hour stay) #1 Unless you’re a designer or a developer, the billboards are pure gibberish.&#xff03;1除非您是設計師或開…

以下屬于linux文件系統認為的文件是,信息安全技術題庫:在Linux系統中,圖形文件、數據文件、文檔文件等都屬于()。...

相關題目與解析Linux中圖像文件屬于()。A、文本文件B、連接文件C、特殊文件D、二進制文件主要用于Linux系統中進程間相互傳遞數據。A&#xff0e;FIFO文件B&#xff0e;設備文件C&#xff0e;鏈接文件D&#xff0e;目錄文件關于Linux文件組織方式的說法中&#xff0c;(32)是錯誤…

關于eclipse中文注釋亂碼的問題

今天打開了一個以前的android項目&#xff0c;發現中文注釋都成亂碼啦&#xff01;&#xff01;&#xff01; 后來在網上找了一會解決方法&#xff0c;知道了中文的編碼大體是兩種&#xff1a;GBK(漢字內碼擴展規范)和UTF-8(8-bit Unicode Transformation Format)。 因此問題的…

園林系統優秀黨員推薦材料_園林綠化公司黨員先進個人事跡材料

第1頁共5頁三一文庫(www.31doc.com)〔園林綠化公司黨員先進個人事跡材料〕我于年月踏出校門來到建設公司。初到公司&#xff0c;我被分配到分公司卉豐園林綠化公司工作。我努力學習公司各項規章制度和相關業務知識&#xff0c;多了解樹木、綠化的有關情況。在此期間&#xff0c…