In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the knowledge of "whether closures are scoped in javascript". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The operating environment of this tutorial: windows7 system, javascript1.8.5 version, Dell G3 computer.
We know that the order in which the scope chain looks for identifiers is to look up one level from the current scope. Therefore, through the scope chain, the variables outside the function can be read inside the JavaScript function, but in turn, the variables inside the function can not be read from the outside of the function. In practical applications, sometimes it is necessary to access the local variables of the function outside the function, and the most commonly used method is to use closures.
Closure is one of the important features of JavaScript and plays an important role in functional programming. This section introduces the structure and basic usage of closures.
So what is a closure?
A closure is a function context active object that can persist, and it is an object that contains references to both function objects and scope objects. Closures are mainly used to obtain variables or values on the scope chain or prototype chain. The most common way to create closures is to declare internal functions (also known as nested functions) in a function and return internal functions.
At this time, outside the function, we can get the internal function by calling the function, and then call the internal function to access the local variables of the function. The inner function at this time is a closure. Although according to the concept of closure, all JavaScript functions that access external variables are closures, most of the time the so-called closures actually refer to internal function closures.
Closures can encapsulate some data as private attributes to ensure secure access to these variables, which brings great benefits to applications. It is important to note that closures can also cause unexpected problems if they are not used properly. Here are a few examples to demonstrate the creation, use, and possible problems of closures and their solutions.
Formation principle
When a function is called, a temporary context active object is generated. It is the top-level object in the scope of the function, and all private methods in the scope, such as variables, parameters, private functions, and so on, will exist as attributes of the context active object.
After the function is called, by default, the context active object is released immediately to avoid taking up system resources. However, if private variables, parameters, private functions, and so on within the function are referenced by the outside world, the contextual active object will continue to exist temporarily until all external references are logged out.
However, the scope of the function is closed and inaccessible to the outside world. So under what circumstances can private members within a function be accessed by the outside world?
According to the scope chain, internal functions can access private members of external functions. If the internal function refers to the private member of the external function, and the internal function is passed to the outside world, or open to the outside world, then the closure is formed. This external function is a closure, after it is called, the active object will not be logged out temporarily, its properties will continue to exist, and the private members of the external function can be read and written continuously through the internal function.
Closure structure
A typical closure is a function of a nested structure. The internal function refers to the private members of the external function, while the internal function is referenced by the outside. When the external function is called, a closure is formed. This function is also called a closure function.
The following is a typical closure structure.
Function f (x) {/ / external function return function (y) {/ / internal function, by returning the internal function, the external reference return x + y; / / access the parameters of the external function};} var c = f (5); / / call the external function to get a reference to the internal function console.log (c (6)); / / call the internal function, the parameters of the original external function continue to exist
The parsing process is briefly described as follows:
During the pre-compilation period of the JavaScript script, the declared function f and variable c are first preparsed by lexical parsing.
During JavaScript execution, the function f is called and the value 5 is passed in.
When parsing function f, the execution environment (function scope) and the active object are created, and parameters and private variables and internal functions are mapped to the properties of the active object.
The parameter x has a value of 5, which maps to the x attribute of the active object.
The internal function refers to the parameter x through the scope chain, but it has not been executed yet.
After the external function is called, it returns the internal function, which causes the internal function to be referenced by the external variable c.
The JavaScript parser detects that the property of the active object of the external function is referenced by the outside world and cannot unregister the active object, so it continues to exist in memory.
When you call c, that is, the internal function, you can see that the value stored in the parameter x of the external function continues to exist. In this way, subsequent operations can be implemented and x+y=5=6=11 is returned.
The following structural forms can also form closures: internal functions are referenced by global variables to open internal functions to the outside world.
Var c; / declare the global variable function f (x) {/ / external function c = function (y) {/ / internal function, by opening to the global variable to achieve external reference return x + y; / / access the parameters of the external function};} f (5); / / call the external function console.log (c (6)); / / call the internal function using the global variable c and return 11
Closure variant
In addition to nested functions, it is also easy to form closures if you externally reference private arrays or objects inside the function.
Var add; / / global variable function f () {/ / external function var a = [1Power2p3]; / / private variable, reference array add = function (x) {/ / test function, open a [0] = x * x; / / modify element value of private array} return a; / / return reference of private array} var c = f () Console.log (c [0]); / / read the array in the closure and return 1add (5); / / Test the modified array console.log (c [0]); / / read the array in the closure and return 25add (10); / / Test the modified array console.log (c [0]); / / read the array in the closure and return 100
Like functions, objects and arrays are referential data. Calling function f returns a reference to the private array a, that is, passing a value to the local variable c, and an is the private variable of function f. When called, the active object continues to exist, thus forming a closure.
This special form of closure has no practical value, because it has a single function and can only be used as a static, one-way closure. The closure function can design all kinds of complex operation expressions, which is the basis of function transformation.
On the other hand, if a simple value is returned, the closure cannot be formed, and the value is passed directly. The external variable c gets only a value, not a reference to the variable inside the function. In this way, when the function is called, the object will be logged out directly.
Function f (x) {/ / external function var a = 1; / / private variable return a;} var c = f (5); console.log (c); / / is only a value and returns 1
Use closures
The following describes the simple use of closures with examples to deepen your understanding of closures.
Example 1
Use closures to achieve elegant packaging and define storage.
Var f = function () {/ / external function var a = []; / Private array initialization return function (x) {/ / return internal function a.push (x); / / add element return a; / / return private array};} () / / directly call function to generate execution environment var a = f (1); / / add value console.log (a) / / return 1var b = f (2); / / add value console.log (b); / / return 1line 2
In the above example, a closure is designed through an external function to define a permanent memory. When the external function is called to generate the execution environment, the returned anonymous function can be used to continuously pass new values to the array an in the closure body, and the passed values will persist.
Example 2
Event handlers can easily form closures in a web page.
Function f () {var a = 1; b = function () {console.log ("a =" + a);} c = function () {a + +;} d = function () {a--;}} View the decreasing value of a
When browsing in the browser, first click the "generate closure" button to generate a closure; click the "View the value of a" button, you can view the value of the private variable an in the closure at any time; click the "increment" and "decrement" button, you can dynamically modify the value of the variable an in the closure, as shown in the figure.
Limitations of closures
The value of closures is to facilitate the storage of data during expression operations. However, its shortcomings can not be ignored.
Because the calling object cannot be logged out after the function call, it will take up system resources, and a large number of closures are used in the script, which can easily lead to memory leakage. Solution: use closures carefully and don't abuse them.
Because of the function of closure, its saved value is dynamic, and it is prone to exceptions or errors if it is not handled properly.
Example
Design a simple tab effect. The structure of HTML is as follows:
Tab1 Tab2 Tab3
Take a look at the JavaScript script next.
_ window.onload = function () {var tab = document.getElementById ("tab"). GetElementsByTagName ("li"), content = document.getElementById ("content"). GetElementByTagName ("div"); for (var I = 0; I < tab.length;i + +) {tab [I] .addEventListener ("mouseover"), function () {for (var n = 0; n < tab.length) N + +) {tab [n] .className = "normal"; content [n] .className = "none";} tab [I] .className = "hover"; content.className = "show";};}}
In the load event handler, use the for statement to bind the mouseover event for each li attribute element; reset the class style of all tabs li in the mouseover event handler, and then set the current li tab highlight while displaying the corresponding content container.
However, when you preview in the browser, you will find that the browser throws an exception.
SCRIPT5007: cannot set the property "className" that is not defined or referenced by null
Trace the value of the variable I in the mouseover event handler, and the value of I becomes 3. The tab [3] is naturally a null, so the className attribute cannot be read.
[cause analysis]
The above JavaScript code is a typical nested function structure. The external function is the load event handler function, the internal function is the mouseover event handler function, and the variable I is the private variable of the external function.
Through event binding, the mouseover event handler is referenced by the outside world (the li element), thus forming a closure. Although event handlers are bound separately for each tab li in the for statement, this operation is dynamic, so the value of I in tab [I] is also dynamic, so the above exception occurs.
[solution]
The easiest way to solve the defect of the closure is to block the variable reference of the internal function to the external function, thus forming the closure body. For this example, we can add a firewall outside the internal function (mouseover event handler) so that it does not refer to external variables directly.
Window.load = function () {var tab = document.getElementById ("tab"). GetElementsByTagName ("li"), content = document.getElementById ("content"). GetElementsByTagName ("div"); for (var I = 0; I < tab.length; I + +) {(function (j) {tab [j] .addEventListener ("number", function () {for (var n = 0; n < tab.length) N + +) {tab [n] .className = "normal"; content [n] .className = "none";} tab [j] .className = "hover"; conteng.className = "show";}) (I);}}
In the for statement, we directly call the anonymous function, pass the I variable of the external function to the calling function, and receive this value in the calling function instead of referencing the external variable I, thus avoiding the confusion caused by the closure body.
That's all for the content of "whether closures are scoped in javascript". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.