Home > Web Front-end > JS Tutorial > body text

Code example explanation of js closure

不言
Release: 2018-10-26 15:48:58
forward
2495 people have browsed it

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
Copy after login

When the following code is not executed inside the function

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

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)
}
Copy after login

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)
Copy after login
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
Copy after login

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)
Copy after login

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
Copy after login

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
Copy after login

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)
}
Copy after login

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)
}
Copy after login

or

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

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
Copy after login

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;))
Copy after login

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'))
Copy after login

Write a sum function and implement the following calling method

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

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!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!