成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JS 閉包(closure)

nihao / 3135人閱讀

摘要:對(duì)數(shù)組函數(shù)而言,相當(dāng)于產(chǎn)生了個(gè)閉包。關(guān)于對(duì)象在閉包中使用對(duì)象也會(huì)導(dǎo)致一些問題。不過,匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其對(duì)象通常指向。由于聲明函數(shù)時(shí)與聲明函數(shù)時(shí)的值是不同的,因此閉包與閉包貌似將會(huì)表示各自不同的值。

這幾天看到閉包一章,從工具書到各路大神博客,都各自有著不同的理解,以下我將選擇性的抄(咳咳,當(dāng)然還是會(huì)附上自己理解的)一些大神們對(duì)閉包的原理及其使用文章,當(dāng)作是自己初步理解這一功能函數(shù)的過程吧。

首先先上鏈接:

簡(jiǎn)書作者波同學(xué)的JS進(jìn)階文章系列: 前端基礎(chǔ)進(jìn)階系列 其他: JS秘密花園 javascript深入理解js閉包 阮一峰《JavaScript標(biāo)準(zhǔn)參考教程》 一不小心就做錯(cuò)的JS閉包面試題

還有一些也很不錯(cuò),但主要是以應(yīng)用為主,原理解釋沒有上面幾篇深入,不過作為閉包的拓展應(yīng)用其實(shí)也可以看一看;

JavaScript中的匿名函數(shù)及函數(shù)的閉包

紅皮書《JS高程》的閉包:
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。

從這句話我們知道:閉包是一個(gè)函數(shù)

    function createComparisonFunction(propertyName) {

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

這段代碼,我們能直接看出,共存在三個(gè)作用域,Global、createComparisonFunction、匿名函數(shù)funciton,因其JS的作用域鏈特性,后者能訪問自身及前者的作用域。而返回的匿名函數(shù)即使在其他地方被調(diào)用了,但它仍可以訪問變量propertyName。之所以還能夠訪問這個(gè)變量,是因?yàn)閮?nèi)部函數(shù)的作用域鏈中包含createComparisonFunction的作用域。我們來深入了解一下,函數(shù)執(zhí)行時(shí)具體發(fā)生了什么?

當(dāng)?shù)谝粋€(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境(Execution Context,也叫執(zhí)行上下文)及相應(yīng)的作用域鏈,并把作用域鏈賦值給一個(gè)特殊的內(nèi)部屬性[[Scope]]。然后,使用this、arguments和其他命名參數(shù)的值來初始化函數(shù)的活動(dòng)對(duì)象(Activation Object)。但在作用域鏈中,外部函數(shù)的活動(dòng)對(duì)象處于第二位,外部函數(shù)的外部函數(shù)處于第三位,最后是全局執(zhí)行環(huán)境(Global Context)。

換一個(gè)栗子:

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

/這個(gè)函數(shù)返回一個(gè)函數(shù)數(shù)組。表面上看,似乎每個(gè)函數(shù)都應(yīng)該返回自己的索引值,位置0的函數(shù)返回0,位置1的函數(shù)返回1,以此類推。但但實(shí)際上,每個(gè)函數(shù)都返回10,為什么?
數(shù)組對(duì)象內(nèi)的匿名函數(shù)里的i是引用createFunctions作用域內(nèi)的,當(dāng)調(diào)用數(shù)組內(nèi)函數(shù)的時(shí)候,createFunctions函數(shù)早已執(zhí)行完畢。

這圖不傳也罷了,畫得忒丑了。
數(shù)組內(nèi)的閉包函數(shù)指向的i,存放在createFunctions函數(shù)的作用域內(nèi),確切的說,是在函數(shù)的變量對(duì)象里,for循環(huán)每次更新的i值,就是從它那兒來的。所以當(dāng)調(diào)用數(shù)組函數(shù)時(shí),循環(huán)已經(jīng)完成,i也為循環(huán)后的值,都為10;

有人會(huì)問,那result[i]為什么沒有變?yōu)?0呢?
要知道,作用域的判定是看是否在函數(shù)內(nèi)的,result[i] = function.......是在匿名函數(shù)外,那它就還是屬于createFunctions的作用域內(nèi),那result[i]里的i就依然會(huì)更新

那么如何使結(jié)果變?yōu)槲覀兿胍哪??也是通過閉包。

    function createFunctions() {
        var result = [];
        
        for (var i=0;i<10;i++) {
            !function(i) {
                result[i] = function() {console.log(i)};
            }(i);
        }
        return result;
    }
    var arr = createFunctions();
    arr[0]();
    arr[1]();
    arr[2]();
    function createFunctions() {
        var result = [];
        function fn(i) {
            result[i] = function() {console.log(i)}
        };
        for (var i=0;i<10;i++) {
            fn(i);
        }
        
        return result;
    }
    var arr = createFunctions();
    arr[0]();
    arr[1]();
    arr[2]();
    var arr = [];
    function fn(i) {
        arr[i] = function() {console.log(i)}
    }
    function createFunctions() {
        for (var i=0;i<10;i++) {
            fn(i);
        }
    }
    fn(createFunctions());
    arr[0]();
    arr[1]();
    arr[2]();

以第一種為例,通過一個(gè)立即調(diào)用函數(shù),將外函數(shù)當(dāng)前循環(huán)的i作為實(shí)參傳入,并存放在立即調(diào)用函數(shù)的變量對(duì)象內(nèi),此時(shí),這個(gè)函數(shù)立即調(diào)用函數(shù)和數(shù)組內(nèi)的匿名函數(shù)就相當(dāng)于一個(gè)閉包,數(shù)組的匿名函數(shù)引用了立即調(diào)用函數(shù)變量對(duì)象內(nèi)的i。當(dāng)createFuncions執(zhí)行完畢,里面的i值已經(jīng)是10了。但是由于閉包的特性,每個(gè)函數(shù)都有各自的i值對(duì)應(yīng)著。對(duì)數(shù)組函數(shù)而言,相當(dāng)于產(chǎn)生了10個(gè)閉包。

所以能看出,閉包也十分的占用內(nèi)存,只要閉包不執(zhí)行,那么變量對(duì)象就無法被回收,所以不是特別需要,盡量不使用閉包。

關(guān)于this對(duì)象
在閉包中使用this對(duì)象也會(huì)導(dǎo)致一些問題。我們知道,this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的;在全局對(duì)象中,this等于window,而當(dāng)函數(shù)被作為某個(gè)對(duì)象的方法調(diào)用時(shí),this等于那個(gè)對(duì)象。不過,匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其this對(duì)象通常指向window。但有時(shí)候由于編寫閉包的方式不同,這一點(diǎn)可能不會(huì)那么明顯。(當(dāng)然可以用call和apply)
    var name = "The Window";
    
    var obj = {
        name:"My Object",
        getName:function () {
            var bibao = function () {
                return this.name;
            };
            return bibao;
        }
    };
    alert(obj.getName()());            // The Window

先創(chuàng)建一個(gè)全局變量name,又創(chuàng)建一個(gè)包含name屬性的對(duì)象。這個(gè)對(duì)象包含一個(gè)方法——getName(),它返回一個(gè)匿名函數(shù),而匿名函數(shù)又返回this.name。由于getName()返回一個(gè)函數(shù),因此調(diào)用obj.getName()();就會(huì)立即調(diào)用它返回的函數(shù),結(jié)果就是返回一個(gè)字符串。然而,這個(gè)例子返回的字符串是"The Window",即全局name變量的值。為什么匿名函數(shù)沒有取得其波包含作用域(或外部作用域)的this對(duì)象呢?

每個(gè)函數(shù)調(diào)用時(shí)其活動(dòng)對(duì)象都會(huì)自動(dòng)取得兩個(gè)特殊變量:thisarguments
內(nèi)部函數(shù)在搜索這兩個(gè)變量時(shí),只會(huì)搜索到其活動(dòng)對(duì)象為止,因此永遠(yuǎn)不可能直接訪問外部函數(shù)中的這兩個(gè)變量。不過,把外部作用域中的this對(duì)象保存在一個(gè)閉包能夠訪問到的變量里,就可以讓閉包訪問該對(duì)象了。

    var name = "The Window";
    
    var obj = {
        name:"My Object",
        getName:function () {
            var that = this;
            return function () {
                return that.name;
            };
        }
    };
    alert(obj.getName()());

thisarguments也存在同樣的問題,如果想訪問作用域中arguments對(duì)象,必須將該對(duì)象的引用保存到另一個(gè)閉包能夠訪問的變量中。

    var name = "The Window";
    
    var obj = {
        name:"My Object",
        getName:function (arg1,arg2) {
            var arg = [];
            arg[0] = arg1;
            arg[1] = arg2;
            function bibao() {
                return arg[0]+arg[1];
            }
            return bibao;
        }
    };
    alert(obj.getName(1,2)())

obj.getName方法保存了其接收到的實(shí)參在它的變量對(duì)象上,并在執(zhí)行函數(shù)結(jié)束后沒有被回收,因?yàn)榉祷氐拈]包函數(shù)引用著obj.Name方法里的arg數(shù)組對(duì)象。使得外部變量成功訪問到了函數(shù)內(nèi)部作用域及其局部變量。

在幾種特殊情況下,this引用的值可能會(huì)意外的改變。

    var name = "The Window";        
    var obj = {
        name:"My Object",
        getName:function () {
            return this.name;
        }
    };

這里的getName()只簡(jiǎn)單的返回this.name的值。

    var name = "The Window";        
    var obj = {
        name:"My Object",
        getName:function () {
            console.log(this.name);
        }
    };
    obj.getName();                        // "My Object"
    (obj.getName)();                      // "My Object"
    (obj.getName = obj.getName)();    // "The Window"

第一個(gè)obj.getName函數(shù)作為obj對(duì)象的方法調(diào)用,則自然其this引用指向obj對(duì)象。
第二個(gè),加括號(hào)將函數(shù)定義之后,作為函數(shù)表達(dá)式執(zhí)行調(diào)用,this引用指向不變。
第三個(gè),括號(hào)內(nèi)先執(zhí)行了一條賦值語句,然后在調(diào)用賦值后的結(jié)果。相當(dāng)于重新定義了函數(shù),this引用的值不能維持,于是返回"The Window"。

閉包與setTimeout()

setTimeout結(jié)合循環(huán)考察閉包是一個(gè)很老的面試題了

    // 利用閉包,修改下面的代碼,讓循環(huán)輸出的結(jié)果依次為1, 2, 3, 4, 5
    for (var i=1; i<=5; i++) { 
        setTimeout( function timer() {
            console.log(i);
        }, i*1000 );
    }
setTimeout的執(zhí)行與我們平常的JS代碼執(zhí)行不一樣,這里需要提到一個(gè)隊(duì)列數(shù)據(jù)結(jié)構(gòu)執(zhí)行的概念。 關(guān)于setTimeout與循環(huán)閉包的思考題

個(gè)人理解:由于setTimeout函數(shù)的特殊性,須等其他非隊(duì)列結(jié)構(gòu)代碼執(zhí)行完畢后,這個(gè)setTimeout函數(shù)才會(huì)進(jìn)入隊(duì)列執(zhí)行棧。

用chrome開發(fā)者工具分析這段代碼,可以先自己分析一次,看看依次彈出什么?
    setTimeout(function() {
        console.log(a);
    }, 0);
    
    var a = 10;
    
    console.log(b);
    console.log(fn);
    
    var b = 20;
    
    function fn() {
        setTimeout(function() {
            console.log("setTImeout 10ms.");
        }, 10);
    }
    
    fn.toString = function() {
        return 30;
    }
    
    console.log(fn);
    
    setTimeout(function() {
        console.log("setTimeout 20ms.");
    }, 20);

    fn();    

答案:

設(shè)置斷點(diǎn)如圖所示,今天剛學(xué)Chrome的開發(fā)者工具,有哪些使用上的錯(cuò)誤還請(qǐng)指出。
我分別給變量a、b、fn函數(shù)都設(shè)置了觀察,變量的值變化將會(huì)實(shí)時(shí)地在右上角中顯示,可以看到,在JS解釋器運(yùn)行第一行代碼前,變量a、b就已經(jīng)存在了,而fn函數(shù)已經(jīng)完成了聲明。接下來我們繼續(xù)執(zhí)行。要注意:藍(lán)色部分說明這些代碼將在下一次操作中執(zhí)行,而不是已經(jīng)執(zhí)行完畢。

把第一個(gè)setTimeout函數(shù)執(zhí)行完畢后也沒有反應(yīng)。我給三個(gè)setTimeout內(nèi)的匿名函數(shù)也加上觀察選項(xiàng),卻顯示不可使用。

所以,下一次執(zhí)行會(huì)發(fā)生什么?對(duì)console出b的值,但是b沒賦值,右上角也看到了,所以顯示undefined。
而console.log(fn)就是將fn函數(shù)函數(shù)體從控制臺(tái)彈出,要注意,console會(huì)隱式調(diào)用toString方法,這個(gè)會(huì)在后面講到。

現(xiàn)在第26行之前(不包括26行)的代碼都已略過,a,b變量也已得到賦值,繼續(xù)執(zhí)行。
重寫了toString方法前:

重寫后:

toString方法是Object所有,所有由它構(gòu)造的實(shí)例都能調(diào)用,現(xiàn)在這個(gè)方法被改寫并作為fn對(duì)象的屬性(方法)保留下來。
console會(huì)隱式調(diào)用toString方法,所以30行的console會(huì)彈出30;

繼續(xù)執(zhí)行,定義setTimeout函數(shù)也是什么沒有發(fā)生,知道調(diào)用fn前。

調(diào)用fn,是不是就會(huì)執(zhí)行setTimeout函數(shù)呢?其實(shí)沒有,我們可以看到call stack一欄已經(jīng)是fn的執(zhí)行棧了,但是依舊沒發(fā)生什么。
但是:

當(dāng)call stack里的環(huán)境都已退出,執(zhí)行棧里沒有任何上下文時(shí),三個(gè)setTimeout函數(shù)就執(zhí)行了,那這三個(gè)時(shí)間戳函數(shù)那個(gè)先執(zhí)行,那個(gè)后執(zhí)行呢?由設(shè)定的延遲時(shí)間決定,這個(gè)延遲時(shí)間是相對(duì)于其他代碼執(zhí)行完畢的那一刻。
不信我們可以通過改變延遲時(shí)間重新試一次就知道了。

我們?cè)诳椿卦瓉淼拈]包代碼:

    // 利用閉包,修改下面的代碼,讓循環(huán)輸出的結(jié)果依次為1, 2, 3, 4, 5
    for (var i=1; i<=5; i++) { 
        setTimeout( function timer() {
            console.log(i);
        }, i*1000 );
    }

先確認(rèn)一個(gè)問題,setTimeout函數(shù)里的匿名函數(shù)的i指向哪兒?對(duì),是全局變量里的i。
setTimeout里的匿名函數(shù)執(zhí)行前,外部循環(huán)已經(jīng)結(jié)束,i值已經(jīng)更新為6,這時(shí)setTimeout調(diào)用匿名函數(shù),里面的i當(dāng)然都是6了。

我們需要?jiǎng)?chuàng)建一個(gè)能夠保存當(dāng)前i值的"盒子"給匿名函數(shù),使得匿名函數(shù)能夠引用新創(chuàng)建的父函數(shù)。

    // 利用閉包,修改下面的代碼,讓循環(huán)輸出的結(jié)果依次為1, 2, 3, 4, 5
    for (var i=1; i<=5; i++) { 
        !function (i) {
            setTimeout( function timer() {
                console.log(i);
            }, i*1000 );
        }(i);
    }

自調(diào)用函數(shù)就是那個(gè)"盒子"

關(guān)于《JavaScript編程全解》中的說明

考慮這個(gè)函數(shù):

    function f(arg) {
        var n = 123 + Number(arg);
        function g() {console.log("n is "+n);console.log("g is called");}
        n++;
        function gg() {console.log("n is "+n);console.log("g is called");}
        
        return [g,gg];
    }

調(diào)用數(shù)組內(nèi)函數(shù)的console結(jié)果是什么?

    var arr = f(1);
    
    arr[0]();            // 對(duì)閉包g的調(diào)用
    // "n is 125"    "g is called"
    
    
    arr[1]();            // 對(duì)閉包gg的調(diào)用
    // "n is 125"    "gg is called"

函數(shù)g與函數(shù)gg保持了各自含有局部變量n的執(zhí)行環(huán)境。由于聲明函數(shù)g時(shí)與聲明函數(shù)gg時(shí)的n值是不同的,因此閉包g與閉包gg貌似將會(huì)表示各自不同的n值。實(shí)際上兩者都將表示相同的值。因?yàn)樗鼈円昧送粋€(gè)對(duì)象。

即都是引用了,f函數(shù)執(zhí)行環(huán)境內(nèi)變量對(duì)象內(nèi)的n值。當(dāng)執(zhí)行f(1)的時(shí)候,n值就已經(jīng)更新為最后計(jì)算的值。

防范命名空間的污染 模塊:

在JavaScript中,最外層代碼(函數(shù)之外)所寫的名稱(變量名與函數(shù)名)具有全局作用域,即所謂的全局變量與全局函數(shù)。JavaScript的程序代碼即使在分割為多個(gè)源文件后,也能相互訪問其全局名稱。在JavaScript的規(guī)范中不存在所謂的模塊的語言功能。

因此,對(duì)于客戶端JavaScript,如果在一個(gè)HTML文件中對(duì)多個(gè)JavaScript文件進(jìn)行讀取,則他們相互的全局名稱會(huì)發(fā)生沖突。也就是說,在某個(gè)文件中使用的名稱無法同時(shí)在另一個(gè)文件中使用。

即使在獨(dú)立開發(fā)中這也很不方便,在使用他們開發(fā)的庫之類時(shí)就更加麻煩了。
此外,全局變量還降低了代碼的可維護(hù)性。不過也不能就簡(jiǎn)單下定論說問題只是由全局變量造成的。這就如同在Java這種語言規(guī)范并不支持全局變量的語言中,同樣可以很容易創(chuàng)建出和全局變量功能類似的變量。

也就是說,不應(yīng)該只是一昧地減少全局變量的使用,而應(yīng)該形成一種盡可能避免使用較廣的作用域的意識(shí)。對(duì)于較廣的作用域,其問題在于修改了某處代碼之后,會(huì)難以確定該修改的影響范圍,因此代碼的可維護(hù)性會(huì)變差。 避免使用全局變量

從形式上看,在JavaScript中減少全局變量的數(shù)量的方法時(shí)很簡(jiǎn)單的。首先我們按照下面的代碼這樣預(yù)設(shè)一下全局函數(shù)與全局變量。

    // 全局函數(shù)
    function sum(a,b) {
        return Number(a)+Number(b);
    }
    // 全局變量
    var position = {x:2,y:3};
    // 借助通過對(duì)象字面量生成對(duì)象的屬性,將名稱封入對(duì)象的內(nèi)部。于是從形式上看,全局變量減少了
    var MyModule = {
        sum:function (a,b) {
            return Number(a)+Number(b);
        },
        position:{x:2,y:3}
    };

    alert(MyModule.sum(3,3));        // 6
    alert(MyModule.position.x);        // 2

上面的例子使用對(duì)象字面量,不過也可以像下面這樣不使用對(duì)象字面量。

    var MyModule = {};            // 也可以通過new表達(dá)式生成
    MyModule.sum = function (a,b) {return Number(a)+Number(b);};
    MyModule.position = {x:2,y:3};

這個(gè)例子中,我們將MyModule稱為模塊名。如果完全采用這種方式,對(duì)于1個(gè)文件來說,只需要一個(gè)模塊名就能消減全局變量的數(shù)量。當(dāng)然,模塊名之間仍然可能產(chǎn)生沖突,不過這一問題在其他程序設(shè)計(jì)語言中也是一個(gè)無法被避免的問題。
通過這種將名稱封入對(duì)象之中的方法,可以避免名稱沖突的問題。但是這并沒有解決全局名稱的另一個(gè)問題,也就是作用域過廣的問題。通過MyModule.position.x這樣一個(gè)較長(zhǎng)的名稱,就可以從代碼的任意一處訪問該變量。

通過閉包實(shí)現(xiàn)信息隱藏
    // 在此調(diào)用匿名函數(shù)
    // 由于匿名函數(shù)的返回值是一個(gè)函數(shù),所以變量sum是一個(gè)函數(shù)
    var sum = (function () {
        // 無法從函數(shù)外部訪問該名稱
        // 實(shí)際上,這變成了一個(gè)私有變量
        // 一般來說,在函數(shù)被調(diào)用之后該名稱就無法再被訪問
        // 不過由于是在被返回的匿名函數(shù)中,所以仍可以繼續(xù)被使用
        var p = {x:2,y:3};
        
        // 同樣是一個(gè)從函數(shù)外無法被訪問的私有變量
        // 將其命名為sum也可以。不過為了避免混淆,這里采用其他名稱
        function sum_internal(a,b) {
            return Number(a)+Number(b);
        }
        // 只不過是為了使用上面的兩個(gè)名稱而隨意設(shè)計(jì)的返回值
        return function (a,b) {
            alert("x = "+p.x);
            return sum_internal(a,b);
        }
    })();
    console.log(sum(3,4));
    // "x = 2"
    // "y"

上面的代碼可以抽象為下面這種形式的代碼。在利用函數(shù)作用域封裝名稱,以及閉包可以使名稱在函數(shù)調(diào)用結(jié)束后依然存在這兩個(gè)特性。這樣信息隱藏得以實(shí)現(xiàn)。

    (function(){函數(shù)體})();

像上面這樣,當(dāng)場(chǎng)調(diào)用函數(shù)的代碼看起來或許有些奇怪。一般的做法是先在某處聲明函數(shù),之后在需要時(shí)調(diào)用。不過這種做法是JavaScript的一種習(xí)慣用法,加以掌握。
匿名函數(shù)的返回值是一個(gè)函數(shù),不過即使返回值不是函數(shù),也同樣能采用這一方法。比如返回一個(gè)對(duì)象字面量以實(shí)現(xiàn)信息隱藏的功能。

    var obj = (function() {
        // 從函數(shù)外部無法訪問該名稱
        // 實(shí)際上,這是一個(gè)私有變量
        var p = {x:2,y:3};
        
        // 這同樣是一個(gè)無法從函數(shù)外部訪問的私有函數(shù)
        function sum_internal(a,b) {
            return Number(a+b);
        }
        
        // 只不過為了使用上面的兩個(gè)名稱而隨意設(shè)計(jì)的返回值
        return {
            sum:function (a,b) {
                return sum_internal(a,b);
            },
            x:p.x
        };
    })();
    
    alert(obj.sum(3,4));     // 7
    alert(obj.x);            // 2
閉包與類

利用函數(shù)作用域與閉包,可以實(shí)現(xiàn)訪問在控制,上一節(jié)中,模塊的函數(shù)在被聲明之后立即就對(duì)其調(diào)用,而是用了閉包的類則能夠在生成實(shí)例時(shí)調(diào)用。即便如此,著厚重那個(gè)做法在形式上仍然只是單純的函數(shù)生命。下面是一個(gè)通過閉包來對(duì)類進(jìn)行定義的例子

    // 用于生成實(shí)例的函數(shù)
    function myclass(x,y) {
        return {show:function () {alert(x+" | "+y)}};
    }
    var obj = myclass(3,2);
    obj.show();        // 3 | 2

這里再舉一個(gè)具體的例子,一個(gè)實(shí)現(xiàn)了計(jì)數(shù)器功能的類。

這里重申一下:JavaScript的語言特性沒有"類"的概念。但這里的類指的是,實(shí)際上將會(huì)調(diào)用構(gòu)造函數(shù)的Function對(duì)象。此外在強(qiáng)調(diào)對(duì)象是通過調(diào)用構(gòu)造函數(shù)生成的時(shí)候,會(huì)將這些被生成的對(duì)象稱作對(duì)象實(shí)例以示區(qū)別。

表達(dá)式閉包

JavaScript有一種自帶的增強(qiáng)功能,稱為支持函數(shù)型程序設(shè)計(jì)的表達(dá)式閉包(Expression closure)。
從語法結(jié)構(gòu)上看,表達(dá)式閉包是函數(shù)聲明表達(dá)式的一種省略形式??梢韵裣旅孢@樣省略只有return的函數(shù)聲明表達(dá)式中的return{}。

    var sum = function (a,b) {return Number(a+b)};
    // 可以省略為
    var sum = function (a,b) Number(a+b);

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/87034.html

相關(guān)文章

  • 談?wù)勎宜斫獾?em>閉包,js、php、golang里的closure

    摘要:當(dāng)初看這個(gè)解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時(shí)網(wǎng)上很多人說閉包是難點(diǎn),各種地方對(duì)閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...

    betacat 評(píng)論0 收藏0
  • 談?wù)勎宜斫獾?em>閉包,js、php、golang里的closure

    摘要:當(dāng)初看這個(gè)解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時(shí)網(wǎng)上很多人說閉包是難點(diǎn),各種地方對(duì)閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...

    zhoutao 評(píng)論0 收藏0
  • 《你不知道的JS》讀書筆記---作用域及閉包

    摘要:注此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀你不知道的后的理解。作用域及閉包基礎(chǔ),代碼運(yùn)行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎(chǔ),JS代碼運(yùn)行的幕后工作者:引擎及編譯器。引擎負(fù)責(zé)JS程序的編譯及執(zhí)行,編譯器負(fù)責(zé)詞法分析和代碼生成。那么作用域就像一個(gè)容器,引擎及編譯器都從這里提取東西。 ...

    denson 評(píng)論0 收藏0
  • 詳解js閉包

    摘要:但閉包的情況不同嵌套函數(shù)的閉包執(zhí)行后,,然后還在被回收閉包會(huì)使變量始終保存在內(nèi)存中,如果不當(dāng)使用會(huì)增大內(nèi)存消耗。每個(gè)函數(shù),不論多深,都可以認(rèn)為是全局的子作用域,可以理解為閉包。 閉包(closure)是Javascript語言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 閉包的特性 閉包有三個(gè)特性: 1.函數(shù)嵌套函數(shù) 2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量 3.參數(shù)和變量不會(huì)...

    Chiclaim 評(píng)論0 收藏0
  • 老生常談之閉包(你不可不知的若干知識(shí)點(diǎn))

    摘要:閉包是什么這是一個(gè)在面試的過程中出現(xiàn)的概率為以上的問題,也是我們張口就來的問題。文章推薦我們面試中在被問到閉包這個(gè)問題是要注意的幾點(diǎn)閉包的延伸,讓面試變得 閉包是什么?這是一個(gè)在面試的過程中出現(xiàn)的概率為60%以上的問題,也是我們張口就來的問題。但是我們往往發(fā)現(xiàn),在面試的過程中我們的回答并不那么讓面試官滿意,我們雖然能張口說出一些但是卻不能系統(tǒng)的對(duì)這個(gè)問題進(jìn)行回答。面試官希望加入自己團(tuán)隊(duì)...

    daydream 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<