Maison > interface Web > js tutoriel > le corps du texte

Exemple de code expliquant la fermeture js

不言
Libérer: 2018-10-26 15:48:58
avant
2505 Les gens l'ont consulté

Cet article vous apporte des exemples de code sur les fermetures js. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Pour être précis, les fermetures sont basées sur le mécanisme normal de traitement de la collecte des ordures. En d'autres termes, généralement après l'exécution d'une fonction (portée de la fonction), toutes les variables qui y sont déclarées seront libérées et recyclées par le garbage collector. Mais la fermeture utilise une astuce pour permettre aux variables de la portée d'être enregistrées et non récupérées après l'exécution de la fonction.

fermeture

définition

Définition MDN

javascriptkit

portée lexicale

chaîne de portée

Lors de l'exécution de la fonction, d'abord Si vous le pouvez Ne trouvez pas la variable en vous-même, puis recherchez-la dans la portée (portée lexicale) où la fonction actuelle est créée. À partir de ce moment, faites attention à l'état actuel de la variable

dans la portée. chaîne. La fonction blog

, ainsi que la variable que vous recherchez dans sa chaîne de portée, constituent ensemble une fermeture

Généralement, les fermetures sont principalement utilisées pour

encapsuler des données.

Données temporaires

Un cas de fermeture typique

function car(){
 var speed = 0
 function fn(){
 speed++
 console.log(speed)
 }
 return fn
}
var speedUp = car()
speedUp() //1
speedUp() //2
Copier après la connexion

Lorsque le code suivant n'est pas exécuté à l'intérieur de la fonction

function fn(){
 speed++
 console.log(speed)
 }
return fn
Copier après la connexion

Après l'exécution du code est terminé Après cela, la variable locale speed à l'intérieur de la fonction sera détruite Puisque le speedUp scalaire global existe toujours (à moins que la page actuelle ne soit fermée, la variable globale existe toujours), alors la portée à l'intérieur de la fonction ne peut pas être détruite, et là. y a-t-il des éléments qui sont toujours utilisés. , ceci est similaire au mécanisme de récupération de place du navigateur. Lorsque nous exécutons speedUp(), il recherchera dans la portée lexicale de la fonction, et un fn est renvoyé dans la fonction, formant ainsi un fermeture, qui est simplement comprise comme

var speed = 0
function fn(){
 speed++
 console.log(speed)
}
Copier après la connexion

Ce morceau de code forme une fermeture Si fn n'est pas renvoyé, les variables locales à l'intérieur de la fonction seront détruites.

Nous pouvons examiner comment le code ci-dessus peut évoluer à l'aide d'instructions d'exécution immédiate et de fonctions d'exécution immédiate :

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)
Copier après la connexion
Cas de fermetures associés

Combien le code suivant produit-il ? Si vous souhaitez sortir 3, comment modifier le code ?

var fnArr = [];
for (var i = 0; i < 10; i ++) {
 fnArr[i] = function(){
 return i
 };
}
console.log( fnArr[3]() ) // 10
Copier après la connexion

Évolution égale

Supposons qu'il n'y ait que deux niveaux de boucles :

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)
Copier après la connexion

Après transformation (exécution immédiate des instructions, processus d'évolution)

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
Copier après la connexion

Encapsuler un objet Car

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
Copier après la connexion

Combien le code suivant produit-il ? Comment générer en continu 0,1,2,3,4

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

Le résultat de sortie est : delayer:5 (5 sorties consécutives lors de l'exécution de setTimeout, le code sera suspendu dans la zone médiane de). ​​la file d'attente des tâches, en attente de i Execute une fois le parcours terminé, et i = 5 à ce moment, donc delayer de sortie :5 (5 sorties consécutives)

Modifié

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

ou

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

Combien produit le code suivant ?

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
Copier après la connexion

Complétez le code pour trier le tableau par nom, âge et n'importe quel champ

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;))
Copier après la connexion

Réponse

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'))
Copier après la connexion

Écrivez une fonction de somme pour implémenter le appel suivant Way

console.log( sum(1)(2) ) // 3
console.log( sum(5)(-1) ) // 4
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal