search
HomeWeb Front-endJS TutorialAn experienced driver will help you thoroughly understand the various pitfalls of JS closures

An experienced driver will help you thoroughly understand the various pitfalls of JS closures

The old driver will help you thoroughly understand the various pitfalls of JS closures

Closures are js Common development techniques, what are closures?

A closure refers to a function that can access variables in the scope of another function. To put it clearly: a closure is a function that can access variables in the scope of other functions. eg:

function outer() {
     var  a = '变量1'
     var  inner = function () {
            console.info(a)
     }
    return inner    // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域
}

Many people will not understand the relationship between anonymous functions and closures. In fact, closures are defined from the perspective of scope, because inner accesses variables in outer scope, so inner is a closure function. Although the definition is very simple, there are many pitfalls, such as this pointer and the scope of variables. A little carelessness may cause memory leaks. Let’s put the problem aside and think about a question: Why can closure functions access the scope of other functions?

Looking at js functions from the perspective of the stack

Basic variables The value of is generally stored in the stack memory, while the value of the object type variable is stored in the heap memory, and the stack memory stores the corresponding space address. Basic data types: Number, Boolean, Undefined, String, Null.

var  a = 1   //a是一个基本类型
var  b = {m: 20 }   //b是一个对象

Corresponding memory storage:

An experienced driver will help you thoroughly understand the various pitfalls of JS closures

When we execute b={m:30}, there is a new object {m:30} in the heap memory , b in the stack memory points to the new space address (pointing to {m: 30}), and the original {m: 20} in the heap memory will be garbage collected by the program engine, saving memory space. We know that js functions are also objects, and they are also stored in heap and stack memory. Let’s take a look at the transformation:

var a = 1;
function fn(){
    var b = 2;
    function fn1(){
        console.log(b);
    }
    fn1();
}
fn();

An experienced driver will help you thoroughly understand the various pitfalls of JS closures

**

The stack is A first-in, last-out data structure:

1 Before executing fn, we are in the global execution environment (the browser is the window scope), and there is a variable a in the global scope;

2 Enter fn. At this time, the stack memory will push an execution environment of fn. This environment contains variable b and function object fn1. Here you can access the variables defined by its own execution environment and the global execution environment

3 Enter fn1. At this time, the stack memory will push an execution environment of fn1. There are no other variables defined in it, but we can access the variables in fn and the global execution environment, because when the program accesses the variables, it moves to the bottom stack. If you find that there is no corresponding variable in the global execution environment, the program will throw an underfined error.

4 As fn1() is executed, the execution environment of fn1 is destroyed by cup, and then fn() is executed, the execution environment of fn will also be destroyed, leaving only the global execution environment, and now there is no b Variables, and fn1 function objects, only a and fn (the function declaration scope is under window)

**

Accessing a variable within a function is judged according to the function scope chain Whether the variable exists, and the function scope chain is initialized by the program according to the execution environment stack where the function is located, so in the above example, we print variable b in fn1, and find the corresponding fn execution environment according to the scope chain of fn1 variable b. So when the program calls a function, it does the following work: prepare the execution environment, initial function scope chain and arguments parameter object

We now look back at the original example outer and inner

function outer() {
     var  a = '变量1'
     var  inner = function () {
            console.info(a)
     }
    return inner    // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域
}
var  inner = outer()   // 获得inner闭包函数
inner()   //"变量1"

When the program finishes executing var inner = outer(), in fact, the execution environment of outer is not destroyed, because the variable a inside it is still referenced by the function scope chain of inner. When the program finishes executing inner(), this Only when the execution environment of inner and outer will be destroyed and adjusted; the book "JavaScript Advanced Programming" recommends: Because closures will carry the scope of the function containing them, because they will occupy more content than other functions, excessive use of closures , will cause excessive memory usage.

Now we understand the closure, the corresponding scope and scope chain, return to the topic:

Pitfall 1: The referenced variables may change

function outer() {
      var result = [];
      for (var i = 0; i<10; i++){
        result.[i] = function () {
            console.info(i)
        }
     }
     return result
}

It seems that each closure function in the result prints a corresponding number, 1, 2, 3, 4,...,10. This is not actually the case because each closure function accesses the variable i in the outer execution environment. Variable i, as the loop ends, i has become 10, so each closure function is executed, and the result prints 10, 10, ..., 10

How to solve this problem?

function outer() {
      var result = [];
      for (var i = 0; i<10; i++){
        result.[i] = function (num) {
             return function() {
                   console.info(num);    // 此时访问的num,是上层函数执行环境的num,数组有10个函数对象,每个对象的执行环境下的number都不一样
             }
        }(i)
     }
     return result
}

Pit point 2: this points to the problem

var object = {
     name: &#39;&#39;object",
     getName: function() {
        return function() {
             console.info(this.name)
        }
    }
}
object.getName()()    // underfined
// 因为里面的闭包函数是在window作用域下执行的,也就是说,this指向window

Pit point 3: Memory leak problem

function  showId() {
    var el = document.getElementById("app")
    el.onclick = function(){
      aler(el.id)   // 这样会导致闭包引用外层的el,当执行完showId后,el无法释放
    }
}
// 改成下面
function  showId() {
    var el = document.getElementById("app")
    var id  = el.id
    el.onclick = function(){
      aler(id)   // 这样会导致闭包引用外层的el,当执行完showId后,el无法释放
    }
    el = null    // 主动释放el
}

Tip 1: Use closures to solve recursive calling problems

function  factorial(num) {
   if(num<= 1) {
       return 1;
   } else {
      return num * factorial(num-1)
   }
}
var anotherFactorial = factorial
factorial = null
anotherFactorial(4)   // 报错 ,因为最好是return num* arguments.callee(num-1),arguments.callee指向当前执行函数,但是在严格模式下不能使用该属性也会报错,所以借助闭包来实现
// 使用闭包实现递归
function newFactorial = (function f(num){
    if(num<1) {return 1}
    else {
       return num* f(num-1)
    }
}) //这样就没有问题了,实际上起作用的是闭包函数f,而不是外面的函数newFactorial

** Tip 2: Use closures to imitate block-level scope**

es6 is not out Previously, there was a variable promotion problem when using var to define variables, eg:

for(var i=0; i<10; i++){
    console.info(i)
}
alert(i)  // 变量提升,弹出10

//为了避免i的提升可以这样做
(function () {
    for(var i=0; i<10; i++){
         console.info(i)
    }
})()
alert(i)   // underfined   因为i随着闭包函数的退出,执行环境销毁,变量回收

Of course, most of them are now defined using es6's let and const.

This article has ended here. For more exciting content, you can pay attention to the JavaScript Video Tutorial column on the PHP Chinese website!

The above is the detailed content of An experienced driver will help you thoroughly understand the various pitfalls of JS closures. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:简书. If there is any infringement, please contact admin@php.cn delete
From Websites to Apps: The Diverse Applications of JavaScriptFrom Websites to Apps: The Diverse Applications of JavaScriptApr 22, 2025 am 12:02 AM

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python vs. JavaScript: Use Cases and Applications ComparedPython vs. JavaScript: Use Cases and Applications ComparedApr 21, 2025 am 12:01 AM

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

The Role of C/C   in JavaScript Interpreters and CompilersThe Role of C/C in JavaScript Interpreters and CompilersApr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript in Action: Real-World Examples and ProjectsJavaScript in Action: Real-World Examples and ProjectsApr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Atom editor mac version download

Atom editor mac version download

The most popular open source editor