function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
函数f2()
是一个é—包å—?如果ä¸ï¼Ÿä¸ºä»€ä¹ˆå‘¢ï¼Ÿ
ä½†åœ¨è¿™ç¯‡æ–‡ç« ä¸ã€‚ How do JavaScript closures work? 为什么会说:
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)
è¿™ä¸æ˜¯ä¸€ä¸ªé—包。一个é—åŒ…å°±æ˜¯å½“ä½ è¿”å›žå†…éƒ¨å‡½æ•°æ—¶ã€‚å†…éƒ¨å‡½æ•°åœ¨ç¦»å¼€ä¹‹å‰ä¼šå…³é—fooçš„å˜é‡ã€‚为什么?
但我ä¸çŸ¥é“我所åšçš„例å和我引用的å¦ä¸€ä¸ªä¾‹å有什么ä¸åŒï¼Œä¸€ä¸ªä¸æ˜¯å°é—。但是一个是。我认为这两个例åæ˜¯ä¸€æ ·çš„ã€‚
ç”案 0 :(得分:3)
是的,f2
是一个é—åŒ…ï¼Œå› ä¸ºå®ƒä»Žå¤–éƒ¨ä½œç”¨åŸŸè®¿é—®å˜é‡ï¼ˆn
)。 (好å§ï¼Œå®ƒä¸æ˜¯çœŸæ£çš„å…³é— - 请å‚阅下é¢çš„更新)。
n
在f1
内声明,而éžf2
;这使它属于f1
çš„èŒƒå›´ã€‚å› æ¤ï¼Œå½“您创建引用f2
的函数n
æ—¶ï¼Œæ ¹æ®å®šä¹‰å®ƒæ˜¯ä¸€ä¸ªé—åŒ…ï¼Œå› ä¸ºå®ƒä½¿ç”¨å…¶ä»–äººçš„å˜é‡ã€‚
<强>更新强>
好的,如果我ç†è§£æ‚¨å·²æ£ç¡®é“¾æŽ¥çš„answer,则表示f2
ä¸æ˜¯ä¸€ä¸ªé—åŒ…ï¼Œå› ä¸ºå®ƒåªæ˜¯è®¿é—®ä¸€ä¸ªå˜é‡å®ƒçš„作用域(就åƒä¸€ä¸ªif
è¯å¥ï¼Œå®ƒåœ¨å¤§æ‹¬å· * ä¸èŽ·å¾—自己的作用域,å¯ä»¥ä½¿ç”¨å¤–部作用域ä¸çš„å˜é‡è€Œä¸éœ€è¦é—包。)
* 更新:原æ¥åªæœ‰å‡½æ•°åœ¨Javascriptä¸èŽ·å–自己的范围,而ä¸æ˜¯ä»»ä½•æ—§å—。但我的观点ä»ç„¶å˜åœ¨......
但是,如果f2
离开f1
的范围(例如通过退回),f1
å°†æˆä¸ºã€‚在这ç§æƒ…况下,它ä»ç„¶å¯ä»¥è®¿é—®n
å˜é‡f1
,å³ä½¿f2
的原始范围ä¸å†å˜åœ¨ï¼ˆå®ƒï¼†ï¼ƒ39;当控制离开函数时退出)。 f1
会关é—&#34; f1
çš„å˜é‡ï¼Œå› æ¤äººä¸ºåœ°å»¶é•¿äº†f2
范围的生命周期。
就个人而言,å³ä½¿å®ƒæ°¸è¿œä¸ä¼šç¦»å¼€f1
,我ä»ç„¶ä¼šå°†f2
称为é—包。如果一个函数åªæ˜¯é€šè¿‡åœ¨å…¶å£°æ˜ŽèŒƒå›´ä¹‹å¤–使用而æˆä¸ºä¸€ä¸ªé—åŒ…ï¼Œå¹¶ä¸”å®ƒåœ¨è¯¥èŒƒå›´å†…çš„è¡Œä¸ºæ— è®ºä»ŽæŠ€æœ¯ä¸Šè®²æ˜¯å¦æ˜¯é—包都没有区别,那么我认为没有æ„义在åšå‡ºåŒºåˆ†ã€‚我甚至会说,如果f1
是å¦ä¸ºå°é—,它是å¦æ˜¯ä¸€ä¸ªå®žçŽ°ç»†èŠ‚,如果它永远ä¸ä¼šç¦»å¼€{{1}}的范围。
å¦ä¸€æ–¹é¢ï¼Œå¿½ç•¥è¿™ç§åŒºåˆ«æ„味ç€ä»»ä½•ä½¿ç”¨å…¨å±€å˜é‡çš„函数都会被称为&#34; closure&#34;ï¼Œå› ä¸ºå®ƒä»Žå¤–éƒ¨ä½œç”¨åŸŸè®¿é—®å˜é‡ã€‚å› æ¤ï¼Œåªæœ‰å½“它离开其所使用的å˜é‡çš„范围时,它æ‰æˆä¸ºé—包这一事实在ä¸å®šä¹‰æ˜¯ä¸€ç§æœ‰ä»·å€¼çš„(尽管是微妙的)区别。
我想我能给出的最明确的ç”案是它ä¸æ˜¯å…³é— 。
ç”案 1 :(得分:1)
它是一个é—åŒ…ï¼Œå› ä¸ºå®ƒå–决于ä¸é—´ï¼ˆå³éžå±€éƒ¨æˆ–全局)范围内的å˜é‡å€¼ï¼Œå¦‚æžœå˜é‡å‘生å˜åŒ–,那么é—包的æ“作也会å‘生å˜åŒ–。值总是相åŒçš„是å¶ç„¶çš„。
但是,您å¯èƒ½å¸Œæœ›å°†é—包返回给f1()
的调用者,以便å¯ä»¥åœ¨å…¶ä»–地方使用。