[{"data":1,"prerenderedAt":623},["ShallowReactive",2],{"post-\u002Fblog\u002F2022\u002F2022-04-18-closure-in-javascript":3},{"id":4,"title":5,"body":6,"description":610,"draft":611,"enableComment":190,"extension":612,"image":613,"meta":614,"navigation":190,"onday":615,"path":616,"seo":617,"stem":618,"summary":619,"tags":620,"__hash__":622},"blog\u002Fblog\u002F2022\u002F2022-04-18-Closure-in-javascript.md","Closure in JavaScript",{"type":7,"value":8,"toc":607},"minimark",[9,24,29,35,38,43,48,51,54,59,66,71,76,79,89,92,95,213,272,290,295,387,423,440,442,447,453,468,471,551,590,597,600,603],[10,11,12],"p",{},[13,14,15,16,23],"em",{},"This post was ",[17,18,22],"a",{"href":19,"rel":20},"https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F528539234\u002Fanswer\u002F2444609012",[21],"nofollow","transported from zhihu answer",".",[10,25,26],{},[13,27,28],{},"And origin question is:",[30,31,32],"blockquote",{},[10,33,34],{},"In js, when a function is executed, it will be destroyed, and correspondingly, the scope of this function will also be destroyed. The form of closure is to return the function in the function, then use a variable in the global to accept the returned function, because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this return function, because as long as there are variables or other things used inside the function, then this function will not be destroyed. So when we use the returned function in the global scope, then the main function will not be destroyed, the scope naturally exists, we can naturally use the variables in the function, and can save the state. I don't know if I understand it this way, right?",[36,37],"hr",{},[39,40,42],"h2",{"id":41},"here-is-origin-answer","Here is origin answer",[30,44,45],{},[10,46,47],{},"The form of closure is to return the function in the function, then use a variable in the global to accept the returned function, because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this return function, because as long as there are variables or other things used inside the function, then this function will not be destroyed. So when we use the returned function in the global scope, then the main function will not be destroyed, the scope naturally exists, we can naturally use the variables in the function, and can save the state.",[10,49,50],{},"What you said is a so long paragraph, so let me first try to break down your understanding, and then analyze it slowly.",[10,52,53],{},"You say",[30,55,56],{},[10,57,58],{},"The form of closure is the return function in the function",[10,60,61,62],{},"That is wrong. JavaScript was originally designed with functional programming in mind, where functions are first-class citizens in the language. This means that functions can be stored in variables like any other type, passed as arguments to other functions, or returned as function execution values. ",[63,64,65],"strong",{},"The function returns a function, which is determined by the language paradigm. Nothing to do with closures.",[10,67,68],{},[63,69,70],{},"So to understand what the form of closure is, we must start with the definition. Its definition is given directly below,",[30,72,73],{},[10,74,75],{},"A closure occurs when a function is executed outside of the lexical scope in which it was defined and can also remember and access the lexical scope in which it was defined.",[10,77,78],{},"According to the above definition, we can know the two characteristics of the closure,",[80,81,82,86],"ul",{},[83,84,85],"li",{},"First, it executes outside the lexical scope in which it was defined.",[83,87,88],{},"Second, it also has access to the lexical scope where it was defined.",[10,90,91],{},"It's a bit of a mouthful to say so, so let's give an example to illustrate.",[10,93,94],{},"first example,",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-javascript shiki shiki-themes github-dark","function fpp() {\n  var a = 2;\n  function bar() {\n    console.log(a);\n  }\n  return bar;\n}\n\nvar baz = foo(); \u002F\u002F Hey, this is the effect of closure\n","javascript","",[103,104,105,122,141,152,164,170,179,185,192],"code",{"__ignoreMap":101},[106,107,110,114,118],"span",{"class":108,"line":109},"line",1,[106,111,113],{"class":112},"snl16","function",[106,115,117],{"class":116},"svObZ"," fpp",[106,119,121],{"class":120},"s95oV","() {\n",[106,123,125,128,131,134,138],{"class":108,"line":124},2,[106,126,127],{"class":112},"  var",[106,129,130],{"class":120}," a ",[106,132,133],{"class":112},"=",[106,135,137],{"class":136},"sDLfK"," 2",[106,139,140],{"class":120},";\n",[106,142,144,147,150],{"class":108,"line":143},3,[106,145,146],{"class":112},"  function",[106,148,149],{"class":116}," bar",[106,151,121],{"class":120},[106,153,155,158,161],{"class":108,"line":154},4,[106,156,157],{"class":120},"    console.",[106,159,160],{"class":116},"log",[106,162,163],{"class":120},"(a);\n",[106,165,167],{"class":108,"line":166},5,[106,168,169],{"class":120},"  }\n",[106,171,173,176],{"class":108,"line":172},6,[106,174,175],{"class":112},"  return",[106,177,178],{"class":120}," bar;\n",[106,180,182],{"class":108,"line":181},7,[106,183,184],{"class":120},"}\n",[106,186,188],{"class":108,"line":187},8,[106,189,191],{"emptyLinePlaceholder":190},true,"\n",[106,193,195,198,201,203,206,209],{"class":108,"line":194},9,[106,196,197],{"class":112},"var",[106,199,200],{"class":120}," baz ",[106,202,133],{"class":112},[106,204,205],{"class":116}," foo",[106,207,208],{"class":120},"(); ",[106,210,212],{"class":211},"sAwPA","\u002F\u002F Hey, this is the effect of closure\n",[10,214,215,216,219,220,223,224,226,227,229,230,232,233,235,236,238,239,241,242,244,245,247,248,251,252,254,255,257,258,260,261,263,264,266,267,269,270,23],{},"The lexical scope of the ",[103,217,218],{},"bar"," function is within the ",[103,221,222],{},"foo"," function. But if the bar function is called directly outside the ",[103,225,222],{}," function, the compiler cannot find the definition of ",[103,228,218],{}," outside the ",[103,231,222],{},", and therefore does not recognize ",[103,234,218],{},", and will throw an error, indicating that ",[103,237,218],{}," is undefined. So if you want to execute the ",[103,240,218],{}," function outside the ",[103,243,222],{}," function, you can use ",[103,246,218],{}," itself as a return value, let the ",[103,249,250],{},"baz"," variable outside ",[103,253,222],{}," receive the ",[103,256,218],{}," function, and then execute it. In this way, the compiler can know that ",[103,259,218],{}," is stored in ",[103,262,250],{}," after ",[103,265,222],{}," is generated, so that the identity of ",[103,268,218],{}," is clear: it is a function. It can be executed outside of ",[103,271,222],{},[10,273,274,275,277,278,280,281,283,284,286,287,289],{},"But according to the language setting of JavaScript, when a function is executed, it can access the lexical scope where it is located. For example, functions in the global scope can access global variables. Similarly, when the ",[103,276,218],{}," function is declared, it can access the scope where it is located, that is, within the ",[103,279,222],{}," function. And the scope in the ",[103,282,222],{}," function has a variable ",[103,285,17],{},", then this a variable can be directly accessed by the ",[103,288,218],{}," function during execution.",[10,291,292],{},[63,293,294],{},"But isn't this about functions returning functions? Then look at the second example",[96,296,298],{"className":98,"code":297,"language":100,"meta":101,"style":101},"function foo() {\n  var a = 2;\n  function baz() {\n    console.log(a);\n  }\n  bar(baz);\n}\n\nfunction bar(fn) {\n  fn();\n}\n",[103,299,300,308,320,329,337,341,349,353,357,373,382],{"__ignoreMap":101},[106,301,302,304,306],{"class":108,"line":109},[106,303,113],{"class":112},[106,305,205],{"class":116},[106,307,121],{"class":120},[106,309,310,312,314,316,318],{"class":108,"line":124},[106,311,127],{"class":112},[106,313,130],{"class":120},[106,315,133],{"class":112},[106,317,137],{"class":136},[106,319,140],{"class":120},[106,321,322,324,327],{"class":108,"line":143},[106,323,146],{"class":112},[106,325,326],{"class":116}," baz",[106,328,121],{"class":120},[106,330,331,333,335],{"class":108,"line":154},[106,332,157],{"class":120},[106,334,160],{"class":116},[106,336,163],{"class":120},[106,338,339],{"class":108,"line":166},[106,340,169],{"class":120},[106,342,343,346],{"class":108,"line":172},[106,344,345],{"class":116},"  bar",[106,347,348],{"class":120},"(baz);\n",[106,350,351],{"class":108,"line":181},[106,352,184],{"class":120},[106,354,355],{"class":108,"line":187},[106,356,191],{"emptyLinePlaceholder":190},[106,358,359,361,363,366,370],{"class":108,"line":194},[106,360,113],{"class":112},[106,362,149],{"class":116},[106,364,365],{"class":120},"(",[106,367,369],{"class":368},"s9osk","fn",[106,371,372],{"class":120},") {\n",[106,374,376,379],{"class":108,"line":375},10,[106,377,378],{"class":116},"  fn",[106,380,381],{"class":120},"();\n",[106,383,385],{"class":108,"line":384},11,[106,386,184],{"class":120},[10,388,389,390,392,393,395,396,398,399,401,402,404,405,407,408,410,411,413,414,416,417,419,420,422],{},"The ",[103,391,218],{}," function is declared outside of ",[103,394,222],{},", ",[103,397,250],{}," is defined inside of ",[103,400,222],{},", and the ",[103,403,222],{}," function can access ",[103,406,218],{},". Now pass ",[103,409,250],{}," to the ",[103,412,218],{}," function, and ",[103,415,218],{}," will execute it after receiving it. At this time, ",[103,418,250],{}," is transferred to the scope execution in ",[103,421,218],{}," by passing, and can access a in the original scope, which is a closure. And it doesn't involve the problem of function returning function.",[10,424,425,426,428,429,431,432],{},"You see, in the first example above, the **",[103,427,218],{}," function is executed after being stored in the ",[103,430,250],{}," variable outside the lexical scope, and can still access the variable a in the lexical scope, which creates a closure.**In the second example, ",[63,433,434,436,437,439],{},[103,435,250],{}," is passed to ",[103,438,218],{}," through parameters, so that it is executed outside the scope and can access a within the scope. This is also the most essential feature of closures.",[10,441,53],{},[30,443,444],{},[10,445,446],{},"Because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this returned function, because as long as there are variables or other things used inside the function, then this function will not be used destroy.",[10,448,449,450],{},"You are right in saying that global variables are not destroyed. But I don't understand what you want to say, maybe you want to say, as long as the reference of a function is not destroyed, then this function will not be destroyed? ",[63,451,452],{},"However, in any case, whether the global variable will be destroyed or not has nothing to do with whether the closure will be destroyed...",[10,454,455,456,458,459,461,462,464,465,467],{},"In the first example above, ",[103,457,250],{}," is defined globally. Stored is a reference to bar. ",[103,460,250],{}," will not be destroyed because it is defined globally, and it does not matter that ",[103,463,218],{}," and ",[103,466,222],{}," will not be destroyed.",[10,469,470],{},"So back to the second example",[96,472,473],{"className":98,"code":297,"language":100,"meta":101,"style":101},[103,474,475,483,495,503,511,515,521,525,529,541,547],{"__ignoreMap":101},[106,476,477,479,481],{"class":108,"line":109},[106,478,113],{"class":112},[106,480,205],{"class":116},[106,482,121],{"class":120},[106,484,485,487,489,491,493],{"class":108,"line":124},[106,486,127],{"class":112},[106,488,130],{"class":120},[106,490,133],{"class":112},[106,492,137],{"class":136},[106,494,140],{"class":120},[106,496,497,499,501],{"class":108,"line":143},[106,498,146],{"class":112},[106,500,326],{"class":116},[106,502,121],{"class":120},[106,504,505,507,509],{"class":108,"line":154},[106,506,157],{"class":120},[106,508,160],{"class":116},[106,510,163],{"class":120},[106,512,513],{"class":108,"line":166},[106,514,169],{"class":120},[106,516,517,519],{"class":108,"line":172},[106,518,345],{"class":116},[106,520,348],{"class":120},[106,522,523],{"class":108,"line":181},[106,524,184],{"class":120},[106,526,527],{"class":108,"line":187},[106,528,191],{"emptyLinePlaceholder":190},[106,530,531,533,535,537,539],{"class":108,"line":194},[106,532,113],{"class":112},[106,534,149],{"class":116},[106,536,365],{"class":120},[106,538,369],{"class":368},[106,540,372],{"class":120},[106,542,543,545],{"class":108,"line":375},[106,544,378],{"class":116},[106,546,381],{"class":120},[106,548,549],{"class":108,"line":384},[106,550,184],{"class":120},[10,552,389,553,392,555,557,558,401,560,404,562,407,564,410,566,413,568,416,570,419,572,574,575],{},[103,554,218],{},[103,556,222],{},", baz is defined inside of ",[103,559,222],{},[103,561,222],{},[103,563,218],{},[103,565,250],{},[103,567,218],{},[103,569,218],{},[103,571,250],{},[103,573,218],{}," by passing, and can access a in the original scope, which is a closure. ",[63,576,577,578,580,581,583,584,586,587,589],{},"Here, ",[103,579,250],{}," is executed in the scope of ",[103,582,218],{},", not globally, and there is no reference to ",[103,585,250],{}," in the global. But this is a closure, so ",[103,588,250],{}," won't be destroyed either.",[10,591,592,593,596],{},"The closure will not be destroyed, it is determined by the JavaScript interpreter. ",[63,594,595],{},"When the interpreter detects that a closure is generated during execution, the lexical scope where the closure is located will be circled by the interpreter and will never be destroyed. It's not because the closure is referenced globally and will not be destroyed, so the closure will not be destroyed either."," It has nothing to do with the global scope.",[10,598,599],{},"Understanding closures is a painstaking process. There are many pitfalls in this regard. The terminology of computer programming is more abstract. Therefore, it is recommended that when you come into contact with a concept, it is best to start with the definition and then contact specific examples, rather than start directly with the examples. **Your sentence \"the function returns a function\" is most likely influenced by some tutorials on the Internet after directly throwing out examples.",[10,601,602],{},"Hope my answer is helpful to you.",[604,605,606],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":101,"searchDepth":124,"depth":124,"links":608},[609],{"id":41,"depth":124,"text":42},"This post was transported from zhihu answer.",false,"md",null,{},"2022-04-18","\u002Fblog\u002F2022\u002F2022-04-18-closure-in-javascript",{"title":5,"description":610},"blog\u002F2022\u002F2022-04-18-Closure-in-javascript","Give the definition of closure in JavaScript and understand it by examples.",[621],"frontend","vhs3GzK2oVbYPfQUZVTeYYrRPE6p1N9T5S7kvy-TlJ4",1777090297458]