Home  >  Article  >  Web Front-end  >  Code example explanation of js closure

Code example explanation of js closure

不言
不言forward
2018-10-26 15:48:582430browse

The content of this article is to explain the code examples of js closure. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

To be precise, closures are based on the normal garbage collection processing mechanism. In other words, generally after a function (function scope) is executed, all variables declared in it will be released and recycled by the garbage collector. But the closure uses a trick to allow the variables in the scope to be saved and not garbage collected after the function is executed.

Closure

Definition

MDN Definition

javascriptkit

Lexical scope

Scope chain

During the execution of the function, first If you can't find the variable from within yourself, then look for it from the scope (lexical scope) where the current function is created. From this point on, you should pay attention to the current state of the variable.

Scope chain Blog

The function, together with the variable it is looking for in its scope chain, together form a closure

Generally, closures are used mainly to

encapsulate data

Temporary data

A typical closure case

function car(){
 var speed = 0
 function fn(){
 speed++
 console.log(speed)
 }
 return fn
}
var speedUp = car()
speedUp() //1
speedUp() //2

When the following code is not executed inside the function

function fn(){
 speed++
 console.log(speed)
 }
return fn

After the code execution is completed, inside the function The local variable speed will be destroyed. Since the global scalar speedUp always exists (unless the current page is closed, the global variable always exists), then the scope inside the function cannot be destroyed, and there are things in it that are always used. This is consistent with The browser's garbage collection mechanism is similar. When we execute speedUp(), it will search in the lexical scope of the function, and a fn is returned in the function, thus forming a closure. It can be simply understood as

var speed = 0
function fn(){
 speed++
 console.log(speed)
}

This piece of code forms a closure. If fn is not returned, the local variables inside the function will be destroyed.

We can take a look at how the above code can evolve using immediate execution statements and immediate execution functions:

Related cases of
function car(){
 var speed = 0
 function fn(){
 speed++
 console.log(speed)
 }
 return fn
}
var speedUp = car()
//1
function car(){
 var speed = 0
 return function (){
 speed++
 console.log(speed)
 }
}
var speedUp = car()
//2
function car(speed){
 return function (){
 speed++
 console.log(speed)
 }
}
var speedUp = car(3)
//3
function car(){
 var speed = arguments[0]
 return function (){
 speed++
 console.log(speed)
 }
}
var speedUp = car()
//4
function car(){
 var speed = 0
 return function (){
 speed++
 console.log(speed)
 }
}
//5 car可以不写,则为匿名函数 
var speedUp = (function car(speed){
 return function (){
 speed++
 console.log(speed)
 }
}
)(3)
closure

How much does the following code output? If you want to output 3, how to modify the code?

var fnArr = [];
for (var i = 0; i < 10; i ++) {
 fnArr[i] = function(){
 return i
 };
}
console.log( fnArr[3]() ) // 10

Equal evolution

Assume there are only two levels of loops:

var fnArr = []
for (var i = 0; i < 2; i ++) {
 fnArr[i] = (function(j){
 return function(){
 return j
 } 
 })(i)
}
fnArr[3]()
//1
var fnArr = [] 
fnArr[0] = (function(j){
 return function(){
 return j
 } 
 })(0)
}
fnArr[1] = (function(j){
 return function(){
 return j
 } 
 })(1)
}
fnArr[3]()
//2
var a = (function(j){
 return function(){
 return j
 } 
 })(0)
}
var b = (function(j){
 return function(){
 return j
 } 
 })(1)
}
b()
//3
var a = (function(j){
 return function(){
 return j
 } 
 })(0)
}
function fn2(j){
 return function(){
 return j
 }
}
var b = fn2(1)
//4
var a = (function(j){
 return function(){
 return j
 } 
 })(0)
}
function fn2(j){
 return function(){
 return j
 }
 return f
}
var b = fn2(1)
//5
var a = (function(j){
 return function(){
 return j
 } 
 })(0)
}
function fn2(j){
 var j = arguments[0]
 function f(){
 return j
 }
 return f
}
var b = fn2(1)

After transformation (immediate execution of statements, evolution process)

var fnArr = []
for (var i = 0; i < 10; i ++) {
 fnArr[i] = (function(j){
 return function(){
 return j
 } 
 })(i)
}
console.log( fnArr[3]() ) // 3
var fnArr = []
for (var i = 0; i < 10; i ++) {
 (function(i){
 fnArr[i] = function(){
 return i
 } 
 })(i)
}
console.log( fnArr[3]() ) // 3
var fnArr = []
for (let i = 0; i < 10; i ++) {
 fnArr[i] = function(){
 return i
 } 
}
console.log( fnArr[3]() ) // 3

Encapsulate a Car object

var Car = (function(){
 var speed = 0;
 function set(s){
 speed = s
 }
 function get(){
 return speed
 }
 function speedUp(){
 speed++
 }
 function speedDown(){
 speed--
 }
 return {
 setSpeed: setSpeed,
 get: get,
 speedUp: speedUp,
 speedDown: speedDown
 }
})()
Car.set(30)
Car.get() //30
Car.speedUp()
Car.get() //31
Car.speedDown()
Car.get() //3

How much does the following code output? How to continuously output 0,1,2,3,4

for(var i=0; i<5; i++){
 setTimeout(function(){
 console.log(&#39;delayer:&#39; + i )
 }, 0)
}

The output result is: delayer:5 (5 consecutive outputs). When executing setTimeout, the code will be hung in the middle area of ​​the task queue until i traversal is completed. Then execute, and at this time i = 5, so delayer:5 is output (5 consecutive outputs)

After modification

for(var i=0; i<5; i++){
 (function(j){
 setTimeout(function(){
 console.log(&#39;delayer:&#39; + j )
 }, 0)//1000-1000*j 
 })(i)
}

or

for(var i=0; i<5; i++){
 setTimeout((function(j){
 return function(){
 console.log(&#39;delayer:&#39; + j )
 }
 }(i)), 0) 
}

How much does the following code output?

function makeCounter() {
 var count = 0
 return function() {
 return count++
 };
}
var counter = makeCounter()
var counter2 = makeCounter();
console.log( counter() ) // 0
console.log( counter() ) // 1
console.log( counter2() ) // 0
console.log( counter2() ) // 1

Complete the code to sort the array by name, age, and any field

var users = [
 { name: "John", age: 20, company: "Baidu" },
 { name: "Pete", age: 18, company: "Alibaba" },
 { name: "Ann", age: 19, company: "Tecent" }
]
users.sort(byName) 
users.sort(byAge)
users.sort(byField(&#39;company&#39;))

Answer

function byName(user1, user2){
 return user1.name > user2.name
}
function byAge (user1, user2){
 return user1.age > user2.age
}
function byFeild(field){
 return function(user1, user2){
 return user1[field] > user2[field]
 }
}
users.sort(byField('company'))

Write a sum function and implement the following calling method

console.log( sum(1)(2) ) // 3
console.log( sum(5)(-1) ) // 4

The above is the detailed content of Code example explanation of js closure. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete