closure
1, Preliminary study on scope
Scope definition: the area where variables (variables act on context) and functions take effect (can be accessed)
Nested functions, the inside can access the outside, and the outside cannot access the inside
No access from the outside to the inside demo:
var a = 123; function test() { var b = 123; } test();// document.write(b);
Inside you can access the outside Demo:
var a = 123; function test() { var b = 0; function demo() { var c = 234; console.log(b);//0 console.log(a);//123 } demo(); // document.write(c);// report errors } test();
2, js running Trilogy
JS forced grid: single thread; Interpretative language
Syntax analysis, full scan ----- > precompile ----- > interpretation and execution
1. Precompiling
Import demo
var a = 123; console.log(a);//123 console.log(a); var a = 123;//undefined
Function declaration overall promotion
function test(){}
Variable declaration promotion
var a; document.write(a); a = 123; //var a = 123; Equivalent to var a;a = 123
A problem that two sentences can't solve
console.log(a); function a(a){ var a = 234; var a = function(){ } a(); } var a = 123;
Precompiled Prelude:
1.imply global implies a global variable: that is, any variable. If the variable is assigned without declaration, this variable will be owned by the global object window.
function test(){ var a = b =1; //Assign 1 to b (undeclared), declare a, and assign a } test(); //var a = 123; First declare a, then assign a value console.log(window.a); console.log(window.b);
2. All declared global variables are window attributes.
window is the global domain; window is the global:
var a = 123; console.log(a);//---->window. A equivalent var a = 123; window { a : 123 //Quite }
Classic demo
function test() { var a = b = 123;}test();console.log(window.b);//undefined, local, not global console log(a);
Declaration of local variables is not allowed demo
function test(){ var b = 123;}test();console.log(window.b);console.log(b);
Precompiled Trilogy
Precompiling occurs immediately before the function is executed
1. Create an AO object execution context
2. Find the formal parameter and variable declaration, take the variable and formal parameter name as the AO attribute name, and the value is undefined
3. Unify the actual parameter value and formal parameter (GO does not)
4. Find the function declaration in the function body, and assign the value to the function body
Example 1
function fn(a){ console.log(a); // function a(){} var a = 123; // var a has read or not, a = 123; console. log(a); // 123 function a() {} / / I haven't seen it for a long time. Console log(a); // 123 var b = function() {} / / it's called a function expression / / you don't need to read var b. after reading it, you can directly B = function() {} console log(b); // function(){} function d(){}}fn(1);
Example 2
function test(a,b) { console.log(a); c = 0; var c; a = 3; b = 2; console.log(b); function b() {} function d() {} console.log(b);}test(1);// Answer 122
Example 3
function test(a, b) { console.log(a); console.log(b); var b = 234; console.log(b); a = 123; console.log(a); function a(){} var a; b = 234; var b = function () {} console.log(a); console.log(b);}test();
Precompiling occurs not only in the function system, but also in the global. The global call generates a GO object with different names and the same steps. window is GO
// GO{// b : 123;// } Function test() {var a = b = 123; console.log (window. B); / / you can access} test()// Ao {/ / A: undefiend / / does not work on B / /} / / but there is no a in go, so window A No
Mr. Cheng goes (global), then AO
// GO{// test:function(){...}// } console. log(test); function test(test) { console.log(test); var test = 234; console.log(test); function test() { }}test(1); var test = 123;// The moment before Ao {/ / / / test is executed / / / / go, there are tests in Ao, and AO / /}
Difficulty 1:
// GO{// global : undefined---->100// fn : function (){...}// }var global = 100;function fn(){ console.log(global);}// AO{// If you don't have anything, print it. Global doesn't have it. Go to go and find it / /}fn ();
Difficulty 2:
global = 100;function fn(){ console.log(global); global = 200; console.log(global); var global = 300;}fn();var global;// Ao {/ / Global: undefined / /} / / answer: undefined 200 has its own. Use its own first
Difficulty 3
// Go {/ / / / only a / / A: undefined / / C: 234 implies the global variable / /} function test() {console. Log (b); / / undefined if (a) {var B = 100;} console. log(b);// Undefined, because if does not go, c = 234// Implies the global variable console log(c);// 234} var a; test();// AO{// b : undefined// }a = 10; console. log(c);// two hundred and thirty-four
Baidu question
function bar(){ return foo; foo = 10; function foo(){ } var foo = 11;}console.log(bar());//Answer: function foo(){}return
Baidu question
console.log(bar());function bar(){ foo = 10; function foo(){} var foo = 11; return foo; //Return if you have overridden the value in front, you will 11}q return
Variable declaration promotion
console.log(b);//undefinedvar b = function () {}
Top difficulty
// GO{// a : undefined,// demo : function () {}// Then a:100; At the moment before the demo is executed, AO / / F: 123 / /}a = 100 is generated; function demo(e){ function e() {} arguments[0] = 2; console. log(e);// 2 if (a) {/ / now the function declaration cannot be placed in if / / A is undefined, and the statement in it does not go. Var B = 123; function c() {/ / pigs can do}} var C; a = 10; var a; console. log(b);// undefined f = 123;// F there is no in Ao. Throwing it to go implies the global variable console log(c);// func unde console. log(a);// 10}var a; Ao {/ / formal parameter E: undefined --- > 1 --- > function e() {}--- > 2 B: undefined C: undefined --- > (function() {}) a: undefined --- > 10} demo (1)// The following is the function outside, global, goconsole log(a);// 100console. log(f);// one hundred and twenty-three
Ji Cheng topic
//typeof(null);---- objectvar str = false + 1; document. write(str);// 1var demo = false == 1; document. write(demo);// False if (typeof (a) & & - true + (+ undefined) + "") {document. Write ('solid Foundation ');}// "Undefined" &&-1 + "Nan" string type + "" if (11 + "11" * 2 = = 33) {document.write ('solid Foundation ');}!! " " + !! "" - !! false||document.write('If you think you can print, you are a pig ')// "" space string true / / "" empty string false// true + false - false == 1 stops / / 1 | (omitted)
Written test questions:
1. In CSS, several display attributes are listed
display : none/block/inline-block/inline...
2. What are the list style attributes in CSS
<div class="box"> <div class="box_1"></div> <div class="box_r"></div></div>
Arranged in parallel, with equal parents and no spacing / / two column layout
4. Use CSS HTML triangle
5. Horizontal and vertical center
6. Write window Foo value
(window.foo || window.foo = 'bar');//If an error is reported in this way, the or is calculated first, and the priority is high (window. Foo | (window. Foo = 'bar')// Look at the brackets first, bar
3, Scope refinement (sections 16-19)
1. Single thread
2. Explanatory language (translation and interpretation)
[[scope]]: each javascript function is an object. We can access some attributes in the object, but some cannot. These attributes are only accessible to the javascript engine, [[scope]] is one of them. [[scope]] refers to what we call a scope, which stores a collection of runtime contexts.
Scope chain: the collection of execution context objects stored in [[scope]]. This collection is chained. We call this chained link scope chain.
3. Runtime context: when the function executes, an internal object AO called runtime context will be created. An execution context defines the environment in which a function is executed. Each time a function is executed, the corresponding execution context is unique. Therefore, calling a function multiple times will lead to the creation of multiple execution contexts. When the function is executed, the execution context will be destroyed.
Find variables: look down from the top of the scope chain.
var a = 100;function test() { var a = 234; console.log(a);//If you have something in yourself, don't GO. In any case, it means that AO is related to GO}test();
Small example
function a(){ function b() { var b = 234; } var a = 123; b(); console.log(a);}var glob = 100;a();// a defined a.[[scope]]---> 0:GO{}// a.doing a.[[scope]]---> 0:AO{}// 1:GO{}
Two AO S are references that point to the same room
function a(){ function b() { var bb = 234; aa = 0; } var a = 123; b(); console.log(aa);}var glob = 100;a();
example
function a() { function b() { function c(){ } c(); } b();}a();a defined a.[[scope]] ---> 0:GOa doing a.[[scope]] ---> 0 : aAO1 : GOb defined b.[[scope]] ---> 0:aAO1:GOb doing b.[[scope]] ---> 0:bAO1:aAO2:GOc defind c.[[scope]] ---> 0:bAO1:aAO2:GOc doing c.[[scope]] ---> 0:cAO1:bAO2:aAO3:GO
4, Closure
1. Definition:
Closures are generated when internal functions are saved externally. Closure will cause the original scope chain not to be released, resulting in memory leakage
2. Closure example
Example 1
function a() { function b(){ var b = 234; console.log(aaa);//123 } var aaa = 123; return b;}var glob = 100;var demo = a();demo();
Example 2
function a() { var num = 100; function b() { num ++; console.log(num); } return b;}var demo = a();demo();//101demo();//102
3. The role of closures
Implement public variables
eg: function accumulator, previously dependent on external variables
function add() { var count = 0; function demo(){ count++; console.log(count); } return demo;}var counter = add();counter();counter();counter();counter();counter();
Can do caching
eg:eater
function test() { var num = 100; function a(){ num++; console.log(num); } // a defined a.[[scope]] 0 : testAO // 1 : GO function b(){ num--; console.log(num); } // b defined b.[[scope]] 0 : testAO // 1 : GO return [a,b];}var MyArr = test();MyArr[0]();// a doing a.[[scope]] 0 : aAO// 1 : testAO *// 2. GOMyArr[1]();// b doing b.[[scope]] 0 : bAO// 1 : testAO *// 2. GO / / because a and B are the same father, the environment is the same, a=b
Cache demo
function eater() { var food = ""; var obj = { eat : function (){ console.log("i am eating " + food); food = ""; }, push : function(myFood) { food = myFood; } } return obj;}var eater1 = eater();eater1.push('banana');eater1.eat();
Encapsulation and property privatization can be realized
eg: Person();
Modular development to prevent pollution of global variables
Function declaration & & differences between function expressions
4. Closure prevention
Closures will cause multiple executing functions to share a public variable. If it is not a special need, try to prevent this from happening
5, Execute function now
Definition: this kind of function is not declared and is released after one execution. Suitable for initialization
Function for initialization function. Executing a function immediately is no different from a function
var num = (function (a, b, c){ var d = a + b + c; return d;}(1, 2, 3))
There are two ways to write immediate execution functions:
- (function (){}()); W3C recommends the first
- (function (){})();
phenomenon
function test() {//Function declaration var a = 123;} ();// Syntax parsing error function test() {var a = 123;} test();// If test is an expression, you can
Above, only expressions can be executed by symbols
function test() { var a = 123;}//Function declaration 123// Function expression test()// Function expression / / function expression can be var test = function() {console. Log ('a ');} ();// For expressions that can be executed by symbols, the function name will be automatically ignored. Var test = function() {console. Log ('a ');} var test = function() { console.log('a');} ();// Execute + function test() {console. Log ('a ');} ();// Minus sign, exclamation mark, multiplication and division can't work (addition and subtraction represent positive and negative), & &, | / / scary (function test() {console. Log ('a ');}) ()(function test { console.log('a');} ()) / / because of the expression executed by the execution symbol, the function name will be automatically ignored (function() {console. Log ('a ');} ()) / / execute functions immediately in many forms
Immediately execute the function to explore to the bottom
Blogging - breadth or depth
Read an article
Alibaba
function test(a,b,c,d) { console.log(a+b+c+d);}(1,2,3,4);//Equivalent to function test (a, B, C, d) {console.log (a + B + C + D);} (1,2,3,4);
Key introduction examples:
function test () { var arr = [];//Ten functions for (VaR I = 0; I < 10; I + +) {arr [i] = function() {document. Write (I + '');}} return arr;} var myArr = test(); for(var j = 0; j < 10; j++){ myArr[j]();}
Why 10
i++
Why are they all 10
arr[i] = function () { document.write(i + ' ');}
Is an assignment statement that assigns a function reference to the current bit of the array, and the function body is document write(i + ’ '); It is not executed before calling. It is not executed until calling. It is all ten when it happens to be executed.
Execution position= Define location
How to solve (the only way) ten small immediate execution functions
function test () { var arr = [];//Ten functions for (VaR I = 0; I < 10; I + +) {(function (J) {arr [J] = function() {document. Write (j + "");}} (i)); } return arr;} var myArr = test(); for(var j = 0; j < 10; j++){ myArr[j]();}// Print I is still 10, / / execute immediately function is executed immediately after reading
6, Closure fine Version (to be seen)
var demo;function test() { var abc = 100; function a(){ console.log(abc); } demo = a;}test();demo();//Save the inside to the outside and generate closures
Alibaba written test question (UC mobile business group) social recruitment question
function test() { var liCollection = document.getElementsByTagName('li'); for(var i = 0; i < liCollection.length; i++){ liCollection[i].onclick = function(){ console.log(i); } }}test();
<!DOCTYPE html><html> <head> <title>hehe</title> <style type="text/css"> *{ margin: 0; padding: 0; } ul{ list-style: none; } li:nth-of-type(2n){ background-color: red; } li:nth-of-type(2n+1){ background-color: green; } </style> </head> <body> <ul> <li>a</li> <li>a</li> <li>a</li> <li>a</li> </ul> <script type="text/javascript"> function test() { var liCollection = document.getElementsByTagName('li'); for(var i = 0; i < liCollection.length; i++){ (function(j){ liCollection[i].onclick = function(){ console.log(j); } }(i)) } } test(); </script> </body></html>
Written test questions
var x = 1;if(function f() {}){ x += typeof f;}console.log(x);//1undefined