Do you understand JavaScript closures?
When I first encountered the concept of closures in JavaScript, I didn't quite understand it. Now, it's not easy to find a well-explained article just by searching some terminology on Baidu. However, the article by Teacher Ruanyifeng titled "Learning JavaScript Closures" can be considered a good article. I don't want to fully copy this excellent work, as it is not my own understanding, but there are parts that are worth referring to. First, I will quote the last two questions that Teacher Ruanyifeng left for readers at the end of this article.
Question 1
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
var f = object.getNameFunc();
console.log(f());
Question 2
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
var f = object.getNameFunc();
console.log(f());
Of course, the results of running these two questions can be obtained just by running the code, but as for why the result is like this, we will explain it later. First, let me talk about my understanding of closures.
Closure
The role of a closure can be inferred from its name, suggesting that it involves the concept of scope. Closure itself means "enclosed," and in JavaScript, the variable scope can be said to be enclosed. In addition, variables inside functions are not visible to the outside, and can also be considered a closed environment. So, how can we access the internal variables? This requires an internal function to help, and therefore we can say that closures must be related to this issue.
Let’s look at an example
Code 1
function func(){
var n = 10;
function shown(){
console.log(n);
}
return shown;
}
var f = func();
f();
Code 2
function func(){
var n = 10;
return n;
}
console.log(func());
We see that the execution results of these two pieces of code are the same; both print out the value of n as 10. Although the result is the same, the internal mechanisms of the execution are quite different.
First, let’s look at Code 2. Every time func() runs, the internal variable n will be initialized, memory will be reallocated, and a value will be assigned. When func() finishes running, n will be destroyed. This is the same as in other programming languages when using custom functions.
As for Code 1, the running mechanism is that when func() runs, n is initialized, which is the same as in Code 2. Then, an internal function named shown is created, and this internal function shown keeps the environment of the scope where the function is located. This environment includes any variable created in this scope, and in this case, the variable n. So, every time f() is called, the result of 10 will be printed. However, n does not need to be initialized every time because n is always kept in memory. Of course, this is not a baseless claim. We can view the shown function as an enclosed environment that stores information about n, but this n was created by func, not by shown(). Inside shown(), there is only the address information of n. If shown() were to destroy this information after running, how would it obtain this information the next time it runs? The information is kept in memory, and the n variable remains in memory and has not been destroyed after func() finishes running. If it had been destroyed, when we call f() again, it would print undefined instead of 10. We can verify this by calling f() multiple times, and as expected, the result is always 10.
(I'm not sure if everyone can understand the above paragraph, the wording may be a bit rough, but I think it should still be clear. If there are any questions, feel free to leave a comment for discussion.)
Through the above introduction, we can roughly understand that a closure solves the problem of accessing internal function variables and keeps variables in memory. Both of these are necessary for something to be called a closure. In other words, in the above Code 1, the shown function can be called a closure.
Variable Scope
Since closures involve the issue of accessing internal function variables, variable scope is something we must understand. I wrote an article before about variable scope in JavaScript "Do You Know the Traps Hidden in Variables in JavaScript?", where you can get a clear understanding of variable scope.
After understanding the concept of closures and variable scope, let’s go back to the two questions from the beginning.
Explanation of the First Two Questions
For Question 1, the result is "The Window" because although the object defines a property name, the this object in the return function(){ return this.name; } does not point to the object. This is because during the execution of object.getNameFunc(), the this object was not initialized. The f() function is called by the "global" object, so the information about the this object saved in the closure is not the object’s information. Therefore, this.name does not refer to the object’s name but the global variable name.
For Question 2, the result is "My Object" because the that variable is initialized in getNameFunc(). Since object.getNameFunc() is called by the object, the this in var that = this points to the object. Therefore, that also points to the object, and the information saved in the closure is the object’s information. Therefore, that.name refers to object.name, so the printed result is "My Object".
I wonder if everyone can understand this explanation. There are many different views about closures online. Some say that the outer function is the closure, while others say that the inner function is the closure. The answer in this article leans toward the latter, and I personally think the former is an incorrect view. Whether it is the outer function or the inner function, their role in closures should be the same, and this is definitely not a problem.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Do you know about the hidden traps in variables in JavaScript?
Publish Date:2025/02/21 Views:178 Category:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
How much do you know about the Prototype Chain?
Publish Date:2025/02/21 Views:150 Category:JavaScript
-
The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start
将 Pandas DataFrame 转换为 JSON
Publish Date:2024/04/21 Views:153 Category:Python
-
本教程演示了如何将 Pandas DataFrame 转换为 JSON 字符串。
在 Pandas 中加载 JSON 文件
Publish Date:2024/04/21 Views:105 Category:Python
-
本教程介绍了我们如何使用 pandas.read_json()方法将一个 JSON 文件加载到 Pandas DataFrame 中。
将 JSON 转换为 Pandas DataFrame
Publish Date:2024/04/20 Views:135 Category:Python
-
本教程演示了如何使用 json_normalize()和 read_json()将 JSON 字符串转换为 Pandas DataFrame。
如何在 JavaScript 中合并两个数组而不出现重复的情况
Publish Date:2024/03/23 Views:86 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。
如何检查 JavaScript 中的变量是否为字符串
Publish Date:2024/03/23 Views:158 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中检查变量是否为字符串。
在 JavaScript 中扁平化一个数组
Publish Date:2024/03/23 Views:113 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中扁平化一个数组。
在 JavaScript 中将浮点数转换为整数
Publish Date:2024/03/23 Views:72 Category:JavaScript
-
本教程列出了在 JavaScript 中将浮点数转换为整数的各种方法。