鍍金池/ 問答/HTML/ JS閉包問題

JS閉包問題

從C++/Java轉(zhuǎn)過來學(xué)JS有點(diǎn)不習(xí)慣,JS閉包這個(gè)表達(dá)式()()連續(xù)兩個(gè)括號(hào)?為什么把還可以把function括起來然后又加一個(gè)()啊。

  
比如這個(gè),把這個(gè)迭代器function括起來,加參數(shù)(i),外面的括號(hào)(0)就表示調(diào)用0了,把0傳進(jìn)去i。
還有這個(gè),
var a = 6;
(function() {
var a = 5;
})();
a = 6//true。
這個(gè)閉包創(chuàng)造新的作用域,閉包一定是()()這種表達(dá)式嗎?為什么是這個(gè)規(guī)范。
抱歉,初學(xué)JS,很不習(xí)慣。

回答
編輯回答
別逞強(qiáng)

() 塊在 JS 就是對(duì)象的意思,把 function 包起來,就是取定義的函數(shù)對(duì)象。這個(gè)括號(hào)你不能理解為函數(shù)定義和調(diào)用中包裹參數(shù)用的,而可以理解為 a * (b + c)("abc" + xyz).length 這里的括號(hào)。

哎,想想還是不扯“閉包”了,我也說不清,多余的刪了。關(guān)于閉包的偏官方文檔鏈接(中文),希望對(duì)您有幫助。

2018年4月3日 18:52
編輯回答
夢(mèng)囈

這里有js閉包的幾個(gè)例子,可以參考下http://www.aazzp.com/2017/11/...

2017年8月11日 23:04
編輯回答
不討喜

閉包不是指兩個(gè)括號(hào)的作用問題,而是指把你想使用的函數(shù)和變量用一個(gè)大的函數(shù)來包起來,變量是在你需要調(diào)用函數(shù)的外面,你每次調(diào)用你需要的那個(gè)函數(shù)時(shí),那個(gè)函數(shù)里面調(diào)用那個(gè)變量是會(huì)常駐在你的內(nèi)存里面的,類似于使用了memcache來存儲(chǔ)數(shù)據(jù)一樣,但是閉包會(huì)有些性能問題,使用不當(dāng)會(huì)導(dǎo)致你所在的環(huán)境出問題。

2018年5月14日 22:42
編輯回答
薄荷綠

閉包是實(shí)現(xiàn)函數(shù)式編程過程中的一部分。在函數(shù)式編程里,函數(shù)的返回值可以是函數(shù)。

函數(shù)調(diào)用可以是fn(), 那么如果,如果函數(shù)可以返回函數(shù)那么就可以otherFn = fn(); otherFn();
寫到一起就可以是fn()();

不像其他語言,函數(shù)式編程的所有函數(shù)都被認(rèn)為是只接收一個(gè)參數(shù),函數(shù)只接受一個(gè)參數(shù)。多個(gè)參數(shù)的函數(shù),比如兩個(gè)參數(shù)的函數(shù),其實(shí)也是接受一個(gè)參數(shù)的函數(shù),只是它的返回值是另外一個(gè)函數(shù)! 比如加法add(2)(5) ,其實(shí) add 只接收一個(gè)參數(shù),然后返回了一個(gè)函數(shù)2+,再以參數(shù) 5 調(diào)用這個(gè)2+ 函數(shù),那個(gè)這個(gè)2+函數(shù)就返回一個(gè)7

var a = 6;

// (function() {
// var a = 5;
// })();
// 可以寫成這樣
function f() { var a = 5; }
f(); 
// 這段代碼可以說是不涉及閉包
// 這個(gè)跟C JAVA里的局部變量沒有區(qū)別,只是他們不支持前一種的調(diào)用而已

a = 6//true。

因?yàn)樵诤瘮?shù)式編程里函數(shù)和基本類型沒有區(qū)別,(function() {var a = 5;}) 的返回值就是一個(gè)函數(shù),var fn = function() {var a = 5;}也沒有問題,然后后面在加一個(gè)()表示函數(shù)調(diào)用(這樣使用的時(shí)候前面加括號(hào)的原因就是改變優(yōu)先級(jí),函數(shù)調(diào)用()的優(yōu)先級(jí)比定義一個(gè)函數(shù)高,所以不加會(huì)出現(xiàn)錯(cuò)誤)。

可能對(duì)初學(xué)者有點(diǎn)兒難的閉包教程:http://zonxin.github.io/post/...

2018年2月23日 15:38
編輯回答
情殺

首先要明確的是js中的基本概念

  1. 作用域
    js主要的作用域形式就是全局作用域函數(shù)作用域(局部作用域),沒有塊級(jí)作用域,不過在ES6中用let聲明的變量具有塊級(jí)作用域的效果。
  2. 執(zhí)行環(huán)境、變量對(duì)象
    執(zhí)行環(huán)境分為全局執(zhí)行環(huán)境和函數(shù)執(zhí)行環(huán)境,就是當(dāng)前代碼的執(zhí)行上下文,簡(jiǎn)單說就是定義了變量或函數(shù)訪問其他數(shù)據(jù)的權(quán)限,控制著變量和函數(shù)的可見性與生命周期,每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的對(duì)象即變量對(duì)象,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。全局環(huán)境是最外圍的,而每個(gè)函數(shù)有自己的執(zhí)行環(huán)境。
  3. 作用域鏈
    代碼在一個(gè)環(huán)境中執(zhí)行時(shí)就會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈,作用域鏈前端始終是當(dāng)前執(zhí)行環(huán)境的變量對(duì)象,下一個(gè)變量對(duì)象來自包含(外部的)環(huán)境,全局執(zhí)行環(huán)境的變量對(duì)象始終是作用域鏈的最后一個(gè)對(duì)象,就像洋蔥一樣,如果你愿意一層一層剝開它的心,就很好理解了。
  4. 立即執(zhí)行函數(shù)表達(dá)式
    ()這括號(hào)有兩種意義,一是指代一個(gè)表達(dá)式,二是表示函數(shù)執(zhí)行。

    //函數(shù)表達(dá)式
    var fuc = function() {};
    //匿名函數(shù)直接執(zhí)行(立即執(zhí)行函數(shù)表達(dá)式)
    (function(){})();

上面的效果就是很好的創(chuàng)建了一個(gè)作用域,可以做到外部作用域中不能夠訪問內(nèi)部,就好像被屏蔽了一樣。所以上面你在全局環(huán)境聲明變量a又在函數(shù)環(huán)境聲明a兩個(gè)就沒什么聯(lián)系了,兩個(gè)處于不同的變量對(duì)象內(nèi)部,雖然名字相同。但是如果你在函數(shù)內(nèi)部不聲明a,而是直接a = 5賦值,則外部的a會(huì)改變,這是因?yàn)閮?nèi)部通過作用域鏈訪問到外部的變量并賦值。理解了作用域鏈就很好理解這些問題了。
最后,什么是閉包?,答:就是能訪問局部變量的函數(shù)??!方式是如下(實(shí)質(zhì)還是通過作用域鏈)

var funcName = function() {
    return function() {
    }
}
2017年8月24日 23:00