日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数表达书-读书笔记

發(fā)布時間:2023/11/29 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数表达书-读书笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

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

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

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

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

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

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

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

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

一、閉包

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

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;}}; }

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

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()時,會創(chuàng)建一個包含arguments、value1、value2的活動對象。全局執(zhí)行環(huán)境的變量對象在compare()執(zhí)行環(huán)境的作用域鏈中則處于第二位,如圖:

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

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

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

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

首先,創(chuàng)建的比較函數被保存在變量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。

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

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

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

?

參考資料

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

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

總結

以上是生活随笔為你收集整理的函数表达书-读书笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。