国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

從理論角度討論JavaScript閉包

2019-11-19 11:53:53
字體:
供稿:網(wǎng)友
概論

在討論ECMAScript閉包之前,先來介紹下函數(shù)式編程(與ECMA-262-3 標(biāo)準(zhǔn)無關(guān))中一些基本定義。 然而,為了更好的解釋這些定義,這里還是拿ECMAScript來舉例。

眾所周知,在函數(shù)式語言中(ECMAScript也支持這種風(fēng)格),函數(shù)即是數(shù)據(jù)。就比方說,函數(shù)可以保存在變量中,可以當(dāng)參數(shù)傳遞給其他函數(shù),還可以當(dāng)返回值返回等等。 這類函數(shù)有特殊的名字和結(jié)構(gòu)。

定義

函數(shù)式參數(shù)(“Funarg”) ―― 是指值為函數(shù)的參數(shù)。

如下例子:

function exampleFunc(funArg) { funArg(); } exampleFunc(function () { alert('funArg'); });

上述例子中funArg的實參是一個傳遞給exampleFunc的匿名函數(shù)。

反過來,接受函數(shù)式參數(shù)的函數(shù)稱為 高階函數(shù)(high-order function 簡稱:HOF)。還可以稱作:函數(shù)式函數(shù) 或者 偏數(shù)理的叫法:操作符函數(shù)。 上述例子中,exampleFunc 就是這樣的函數(shù)。

此前提到的,函數(shù)不僅可以作為參數(shù),還可以作為返回值。這類以函數(shù)為返回值的函數(shù)稱為 _帶函數(shù)值的函數(shù)(functions with functional value or function valued functions)。  

(function functionValued() {
        return function () {
            alert('returned function is called');
            };
    })()();//這種()直接執(zhí)行的方式要熟悉。

可以以正常數(shù)據(jù)形式存在的函數(shù)(比方說:當(dāng)參數(shù)傳遞,接受函數(shù)式參數(shù)或者以函數(shù)值返回)都稱作 第一類函數(shù)(一般說第一類對象)。 在ECMAScript中,所有的函數(shù)都是第一類對象。

接受自己作為參數(shù)的函數(shù),稱為 自應(yīng)用函數(shù)(auto-applicative function 或者 self-applicative function):

(function selfApplicative(funArg) { if (funArg && funArg === selfApplicative) { alert('self-applicative'); return; } selfApplicative(selfApplicative); })();

以自己為返回值的函數(shù)稱為 自復(fù)制函數(shù)(auto-replicative function 或者 self-replicative function)。 通常,“自復(fù)制”這個詞用在文學(xué)作品中: 

(function selfReplicative() {
        return selfReplicative;
    })(); 

在函數(shù)式參數(shù)中定義的變量,在“funArg”激活時就能夠訪問了(因為存儲上下文數(shù)據(jù)的變量對象每次在進(jìn)入上下文的時候就創(chuàng)建出來了):

function testFn(funArg) { // 激活funArg, 本地變量localVar可訪問 funArg(10); // 20 funArg(20); // 30 } testFn(function (arg) { var localVar = 10; alert(arg + localVar); });

然而,我們知道,在ECMAScript中,函數(shù)是可以封裝在父函數(shù)中的,并可以使用父函數(shù)上下文的變量。 這個特性會引發(fā) funArg問題。

FunArg問題

面向堆棧的編程語言中,函數(shù)的本地變量都是保存在堆棧上的, 每當(dāng)函數(shù)激活的時候,這些變量和函數(shù)參數(shù)都會壓棧到該堆棧上。

當(dāng)函數(shù)返回的時候,這些參數(shù)又會從堆棧中移除。這種模型對將函數(shù)作為函數(shù)式值使用的時候有很大的限制(比方說,作為返回值從父函數(shù)中返回)。 絕大部分情況下,問題會出現(xiàn)在當(dāng)函數(shù)有 自由變量的時候。

自由變量是指在函數(shù)中使用的,但既不是函數(shù)參數(shù)也不是函數(shù)的局部變量的變量

如下所示:

function testFn() { var localVar = 10; function innerFn(innerParam) { alert(innerParam + localVar); } return innerFn; } var someFn = testFn(); someFn(20); // 30

上述例子中,對于innerFn函數(shù)來說,localVar就屬于自由變量。

對于采用 面向堆棧模型來存儲局部變量的系統(tǒng)而言,就意味著當(dāng)testFn函數(shù)調(diào)用結(jié)束后,其局部變量都會從堆棧中移除。 這樣一來,當(dāng)從外部對innerFn進(jìn)行函數(shù)調(diào)用的時候,就會發(fā)生錯誤(因為localVar變量已經(jīng)不存在了)。

而且,上述例子在 面向堆棧實現(xiàn)模型中,要想將innerFn以返回值返回根本是不可能的。 因為它也是testFn函數(shù)的局部變量,也會隨著testFn的返回而移除。

還有一個函數(shù)對象問題和當(dāng)系統(tǒng)采用動態(tài)作用域,函數(shù)作為函數(shù)參數(shù)使用的時候有關(guān)。

看如下例子:

var z = 10; function foo() { alert(z); } foo(); // 10 

主站蜘蛛池模板:
鄱阳县|
成安县|
都兰县|
工布江达县|
新安县|
青田县|
周口市|
普安县|
东辽县|
苏尼特左旗|
漳浦县|
汨罗市|
房山区|
高安市|
石狮市|
温宿县|
枝江市|
收藏|
永仁县|
铜川市|
巨鹿县|
长宁区|
温泉县|
潮州市|
诏安县|
西乡县|
瑞丽市|
上林县|
常州市|
安吉县|
苍梧县|
林州市|
凤山县|
怀来县|
泰兴市|
宝丰县|
东台市|
油尖旺区|
普兰县|
建始县|
隆化县|