JavaScript closures - the hardest hit area for interviews, how to deal with them?

1. Closure - the hardest hit area for interviews

During the recent interview process, when asked about JavaScript closures, most of them were confused.

Closure, you say it is important, it is really important, after all, this is a development technique widely used by many front-end frameworks. You say it's not important, and it's really not that important, because our development projects basically apply the existing framework, write code within the scope of the framework, and rarely use closures.

However, I can't bear to be asked frequently in interviews.

In this section, let's talk about the topic of closures!

2. Under what circumstances will a closure be generated

Let's look at an example:

function f(){
    let a = 1;

    return function(){
        console.log(a);
    }
}  

f()()

a is a variable inside the function f. It stands to reason that after the function ends, the outside cannot access a.

But if we use a function to access a and then return the function, the life cycle of a is continued.

The result of the above code is 1.

Not only that, we can also operate a repeatedly outside.

3. Closures will produce spooky ghost variables

In the above example, we quietly sent the a variable out of the function f, and then we can repeatedly ravage it!

function f(){
    let a = 1;

    return function(increment){
        a += increment;
        console.log(a);
    }
}  

f()(1)

The answer is 2, it can be seen that we can operate on the a variable outside. Let's think about a question, what if I operate it multiple times?

var inner = f();
inner(1);
inner(1);
inner(1);

Answer

 It can be seen that if you operate it multiple times, the same a variable is operated. This a variable is like a ghost. You can't see it outside, but it really exists.

4. Closures can be combined with objects

Look directly at the following example, there is a certain practical significance

var obj = {}

function f(){
    let a = 1;
    obj.num = a;
    obj.get = function(){
        return a;
    }
    obj.set = function(v){
        a = v;
    }

}  

f()

This code is different from the previous one. It does not directly return another function in the function f, but gives some properties and methods to the outside obj object. It's amazing, but this is allowed by the syntax.

After the function f is run, the value of obj.num must be 1 at a glance

What if I do this?

obj.num += 1;

 This way, obj.num is equal to 2

But what value does obj.get() get?

Still 1, this is because a is the number 1 of the basic type, and  obj.num = a  is actually a copy of the value, we can't change the size of num to change a synchronously, they are two variables. And  obj.get , obj.set operation is the real a

Above we said that a is the number 1 of the basic type, and  obj.num = a  is actually a value copy, so if a is an object type, it can be operated.

let a = {};
obj.a = a;
obj.get = function(){
    return a;
}
obj.set = function(v){
    a = v;
}

Well, from this example, it is not difficult to find that the biggest role of the closure is to extend the life cycle of some variables inside the function. But because of this, closures may cause some memory leaks. However, in most cases, this memory leak is really harmless.

Some students may say that I don't need a closure. The big deal is to set an attribute a in obj, the same.

In this example, it does.

However, in some special cases, it is really necessary to use closures.

5. Closure combat - Vue data binding 

In Vue, we know that there will be an initialization process that will hold all properties in data in order to trigger watcher updates. Below is the simplified code

var data = {
    username:'',
    password:''
}

for(let key in data){
    Object.defineProperty(data,key,{
        set(v){
            data[key] = v
        },
        get(){
            return data[key]
        }
    })
}

This code looks fine at first glance, but when we assign a value to username, the set method will be triggered

 The error is because a circular reference occurs, and the set is triggered repeatedly.

Similarly, get will also report an error

 

 How can we do this, do we have to have a temporary variable to save the value of the current property?

like this

for(let key in data){
    let value = data[key]
    Object.defineProperty(data,key,{
        set(v){
            value = v
        },
        get(){
            return value
        }
    })
}

Instantly perfect.

 It stands to reason that value is just a temporary variable in the for loop. Because let is used, it is only valid in the current scope. And this temporary value is accessed by the set and get methods, so its life cycle continues!

So, my understanding of closures is that a function accesses an external variable, and the function will use this variable at some point in the future, which is a closure.

Guess you like

Origin blog.csdn.net/weixin_39570751/article/details/123161134