The concept and application of closure in JavaScript advanced
Source: Internet
Author: User
Main Content: What are the general mode closures used by closure closures? This article is the second article in my JavaScript advanced series. in this series, I plan to analyze some common and mysterious advanced content in JavaScript, including scope... syntaxHighlighter. all (); main content: What is the general mode closure used by the closure can do? This article is the second article in my JavaScript advanced series. in this series, I plan to analyze some common and mysterious advanced content in JavaScript, including scope chain, closure, function call form, object-oriented content. this article describes the closure. when it comes to JavaScript, we can think of closure as a magic thing. what is a closure and how to use it? Let's analyze it today! Similarly, this is an advanced part of JavaScript. It is very important for JavaScript to have a basic foundation. for basic syntaxes and the basic features of dynamic languages, you may not want to know much about it, find a book or some information about the system. this will help you understand the following article. of course, you can also http://net.itcast.cn To download something. the topic of today is officially entered below. 1. What is a closure? The word "closure" is not unique in JavaScript. Actually, a closure is a unique concept. as for the concept itself, I have not introduced it much. Baidu has everything. I mainly talk about the closure in JavaScript. in JavaScript, closures are function closures and functions. This concept seems a bit confusing. actually, closure is the scope of a closed package. as mentioned above, functions can limit the scope of variables. if a variable is declared inside the function, it cannot be accessed outside the function. this is a closed range. in a broad sense, it is a closure! This is actually meaningless. because there is nothing special, but if a function is defined in the function and returned in the form of a return value, then, in JavaScript, the "subdomain access parent domain" rule will be broken. at this time, variables in the function can be accessed outside the function. see the following code: 1 var func = function () {2 var num = 10; 3 return function () {4 alert (num); 5}; 6 }; 7 var foo = func (); 8 foo (); in this Code, the function foo is a 0-level chain, and the variable num is in a 1-level chain. At this time, the 0-level chain function accesses the variable num in the 1-level chain, and the running result of this Code is printed 10. in this way, the closure in JavaScript is implemented. in summary, the closure in JavaScript defines the variables in the function, and then returns the function that can access the variables through the return value, so that the variables in the function can be accessed outside the function.. This forms a closure. 2. There are many cases of closure and its description. in JavaScript, using closures is like using pointers in C. its basic syntax is simple, but its usage is flexible. Using its flexible syntax and features can implement many very powerful functions. we cannot describe all the usage of closures here, but for those who have just come into contact with closures, the following cases are enough to understand for a while. 2.1 The case of simulating private members is the basis for implementing object-oriented JavaScript. see the following code 1 var Person = function (name, age, gender) {2 return {3 get_name: function () {4 return name; 5}, 6 set_name: function (value) {7 name = value; 8}, 9 get_age: function () {10 return age; 11}, 12 ge T_gender: function () {13 return gender; 14} 15}; 16}; this code is a function with three parameters, that is, there are three local variables in the function, name, age, and gender, respectively ). then, an object is returned in the return value, which provides four methods. read and Write methods are provided for age, and read methods are provided for gender and age respectively. these four functions are subdomains of the function. therefore, the returned object can directly access these three variables. however, the read/write permission is limited. 2.2 Fibonacci series: 1, 1, 2, 3, 5, 8, 13 ,... this is a frequently used case in the interview questions. It is also a representative algorithm question. see the following code: 1 // For simplicity, n is not judged to process 2 var Fib = (function () {3 var fibArr = [1, 1]; 4 ret Urn function (n) {5 var res = fibArr [n]; 6 if (res) {7 return res; 8} else {9 res = arguments. callee (n-1) + arguments. callee (n-2); 10 fibArr. push (res); // return res; 11} 12}; 13}) () is missing. In this case, recursion is used, however, the recursive performance problem is terrible. If you are interested, you can calculate the number of the 20th results of this series and count the number of recursive calls of this function. the following code is as follows: 1 var count = 0; 2 var fib = function (n) {3 count ++; 4 // 5 if (n = 0 | n = 1) return 1; 6 return fib is not processed for the sake of simplicity. (N-1) + fib (n-2); 7}; 8 var res = fib (20); 9 the result of alert ("fib (20) is:" + res + ", the function calls "+ count +" times "). Then, use the new method to calculate the same result and count the number of times. 1 var count = 0; // 2 var Fib = (function () {3 var fibArr = []; 4 return function (n) is processed for the sake of simplicity without making n judgments) {5 count ++; 6 var res = fiber arr [n]; 7 if (res) {8 return res; 9} else {10 res = arguments. callee (n-1) + arguments. callee (n-2); 11. push (res); 12 return res; 13} 14}; 15}) (); 16 var res = Fib (20); 17 alert ("Fib (20) Results:" + res + ", the function calls "+ count +" times "). I will not reveal this result here. Please run it on your own. the code for this new method is analyzed below. in this Code, the function bound to Fib is actually the result returned by the subsequent function. the following function has a private variable, which is an array. the values of the 0th and 1st arrays are saved. then return a function. the returned function is executed when Fib (20) is called. in this function, first access the nth value of the array. If this data exists in the array, it will be returned directly. Otherwise, this value will be calculated recursively and added to the array, finally, the calculation result is returned. in JavaScript, arguments. callee () indicates the current call of a function (that is, a recursive function ). in this case, the most direct result is that there is a cache that stores the calculated results in Cache, and all computation is performed only once, so the performance can be greatly improved. 2.3 html string case this is a method used by many js libraries. In many js libraries, regular expressions are required to process some data, if each row is saved in the method to process matched strings, memory consumption will be high, affecting performance. therefore, you can save the expressions that are used repeatedly in the closure, and the string is accessed every time you use them. example: 1 String. prototype. deentityify = function () {2 var entity = {3 lt: '<', 4 gt: '> '5}; 6 return function () {7 return this. replace (/& ([^;] +);/g, function (a, B) {8 var r = entity [B]; 9 return typeof r === 'string '? R: a; 10}); 11}; 12} (); this code replaces <and> in any string with Angle brackets. <和> It is very useful for copying html code on pages. 2.4 append and remove of event processing methods does not support append of event processing functions in JavaScript. master Jeremy Keith provides a solution: 1 var loadEvent = function (fn) {2 var oldFn = window. onload; 3 if (typeof oldFn = "function") {4 window. onload = function () {5 oldFn (); 6 fn (); 7}; 8} else {9 window. onload = fn; 10} 11}; however, this code cannot remove the method that has been appended, so you can use the cache function of the closure to easily implement it. 1 var jkLoad = (function () {2 var events = {}; 3 var func = function () {4 window. onload = function () {5 for (var I in events) {6 events [I] (); 7} 8}; 9}; 10 return {11 add: function (name, fn) {12 events [name] = fn; 13 func (); 14}, 15 remove: function (name) {16 delete events [name]; 17 func (); 18} 19}; 20}) (); this code is used to obtain the object used to append and remove the load event. if you want to append an event, you can use 1 jkLoad. add ("f1", function () {2 // execute code 13}); To remove an event handler, use code 1 jkLoad. remove ("f1"); then this case can be extended to the corresponding object to append the specified event. How can this problem be achieved? Let's think about it !!! 3. Now, we have analyzed what the closure is and the general implementation method of the closure. Finally, we have analyzed several closure cases. I think you should have a deeper understanding of closures. in the later object-oriented and other advanced content, we will see the power of the closure again. next, let's answer the previous question: 1 var func = function () {2 alert ("calling functions outside"); 3}; 4 var foo = function () {5 func (); 6 7 var func = function () {8 alert ("calling internal functions"); 9}; 10 11 func (); 12 }; this code will report an error in IE, but it does not have any effect in FF and Chrome, because the first function call func () in foo will report an error and an exception occurs, therefore, the subsequent code is not executed. if you need to modify it, you only need to try-catch it. example: 1 var func = func Tion () {2 alert ("calling functions outside"); 3}; 4 var foo = function () {5 try {6 func (); 7} catch (e) {8 alert (e); 9} 10 var func = function () {11 alert ("calling internal functions"); 12}; 13 14 func (); 15 }; the second question: 1 if (! "A" in window) {2 var a = "define variable"; 3} 4 alert (a); this code returns undefined. first, there is no function in this code, so the variables defined in if will be in advance, that is, equivalent to 1 var a; 2 if (! "A" in window) {3 var a = "defining variables"; 4} 5 alert (); the in operator is used to determine whether the attribute represented by the string on the left is a member of the object on the right. in the browser, the Global Object of JavaScript is window, and the directly defined variable is actually an attribute of the global object. Therefore, if the variable a has been defined, then "a" in window returns true, and returns the inverse value, that is, false. Therefore, if code is not executed, a is not assigned, so the printed result is undefined. the above code is equivalent to: 1 var a; 2 if (false) {3 a = "definition variable"; 4} 5 alert ();
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.