Let’s start with the definition from Wikipedia
In computer science, closure (English: Closure), also known as Lexical Closure or function Closures are functions that reference free variables. The referenced free variable will remain with the function even after it has left the environment in which it was created. Therefore, there is another way of saying that a closure is an entity composed of a function and its associated reference environment. Closures can have multiple instances at runtime, and different reference environments and the same function combination can produce different instances.
To simply understand this sentence, there are two key points:
1. Free variable 2. Function (referencing free variable).
When we define a variable, if we do not specify constraints on it, it is a free variable.For example:
x ∈ (0,99) f(x,y)
In the function f(x,y), x is the constraint variable and y is the free variable.
Specifically in JavaScript, let’s look at an example:
var x = 0; function foo (y) { var z = 2; return x + y + z;}foo (3); // 3
If converted into mathematical thinking, the function foo should actually be like this: foo(x,y) , but we know that the parameters of the function are actually constrained by the function, that is to say, the real free variable is only x.
This can lead to a simple definition,In a function, if there is a variable that is neither a local variable nor a formal parameter, we can think of it as forming a closure.
In almost all languages, variables with the same name are searched nearby. First, they are searched in this scope. If they cannot find it, they go to the parent scope. We call this a scope chain.
In a closure function, free variables are usually provided by the parent. Look at the following example:
function foo(x) { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); } bar(10);}foo(2)
According to our definition above, bar has free variables and is a closure, but foo does not.
So how can we make foo a closure?
var x = 0;function foo() { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); } bar(10);}// 其实转换一下,形如function foo2() { var tmp = 3; //function bar(y) { console.log(x + 10 + (++tmp)); //} // bar(10);}
At this point, foo can be considered a closure.
At this point, some friends may think that this is different from the js closures we usually see. The closures we usually see are like this: the example comes from this blog
function foo(x) { var tmp = new Number(3); return function (y) { alert(x + y + (++tmp)); }}var bar = foo(2); // bar 现在是一个闭包bar(10);
This function can actually be rewritten as follows:
bar = function (y) { // foo(2) alert(2 + y + (++tmp))}
Obviously, tmp is a free variable, which conforms to our original definition, and bar is owned function of free variables.
So where does tmp exist?
When foo(2) is executed, a variable with tmp=3 will be generated. This variable is referenced by the return function, so it will not be recycled. The free variables in the return function find values according to the scope chain. The bar function is defined in foo(2), so the variable tmp is first searched for in the variable area of foo(2) and operated on.
Note: Regarding the issue of scope chain, I will analyze it in the next article.
Speaking of which, insertmodule mode.
var Module = (function () { var aaa = 0; var foo = function () { console.log(aaa); } return { Foo: foo }})();// 或者(function () { var aaa = 0; var foo = function () { console.log(aaa); } window.Module = { Foo: foo }})();
Note the above two examples, the Module itself is just an object, but the return function itself forms a closure , ensuring that the scope is clean and will not pollute other functions.
Speaking of this, some friends must think that this is an alternative category? Have local variables and accessible functions. Yes, in terms of appearance, I think closures and classes are very similar.
Take Java as an example:
class Foo { private int a; int Say( int b ) { return a + b; } }
In the above Foo, the a in the function Say is outside the function scope and belongs to free variables. Say can be considered to form a function closure. But the difference from js is that instance methods need to be called through instances of classes, that is, objects.
In the design of java, access permissions, private, protect, default, and package are clarified, which is a pioneering work in standardizing calls. This also makes Java programmers rarely consider the implementation of closures, because variables and functions have keywords to define access permissions and belong to each class, which is clear and clear.
If you understand closure according to the implementation of a class, it is easy to understand why it is not recommended to use closure.
Every time a closure is called, a scope will be generated to store some free variables required by the closure function. This can easily cause memory waste. Even in Java programming, it is not recommended to create new objects casually.
In the previous article bind, call, apply, I mentioned a point,Because it is object-oriented, there is a need to bind this.
Regarding object-oriented, I think the advantage of object-oriented is that it is easy to understand, maintain and reuse. This far exceeds the performance requirements when multiple people develop large projects.
Even now that Moore's Law is slowing down, memory is very cheap compared to before. Therefore, performance requirements have been extreme since ancient times, and code readability is now generally advocated.
There are super experts who have created this colorful world of code. In order to let more people experience the fun of programming, they have designed easier-to-understand programming languages and invented various compilers and parsers...
If you just write a 1+1 program, there is no need to be object-oriented. If humans can have super logic and memory with machines, there is no need to be object-oriented.
The above is the detailed content of How to understand closures and classes in js. For more information, please follow other related articles on the PHP Chinese website!