Recently I have also experienced interviewing others and going to the interview, summarize a few commonly mentioned interview questions, do some answers and notes.

How does this work in JavaScript?

Let’s take a look at this first:

var x = 0;
var foo = {
    x:1,
    bar:{
    x:2,
    baz: function () {
       console.log(this.x)
     }
    }
}

var a = foo.bar.baz
foo.bar.baz() // 2
a() //0
Copy the code

  • This always refers to the object on which the function was run, not the object on which the function was created
  • Anonymous functions and functions that are not in any object. This refers to window
  • Call, apply, with This is who it is.
  • Normal function calls. This refers to whoever the function is called by

In the above example, baz is called by bar so it refers to the object on which bar. a is run, so it refers to Window.

Scope chain?

Understand the execution environment and context

Function calls have scope and context associated with them. Basically, the scope is function-based and the context is object-based. In other words, the scope is related to the access to a variable each time a function is called, and each call is independent. The context is always the value of the this keyword and is a reference to the object calling the current executable code.

Execution contexts include global, function, and eval. A function can generate numerous execution contexts. A series of execution contexts logically form a stack of execution contexts, with the bottom of the stack always being the global context and the top being the current (active) execution context.

Execute context three properties: this pointer, variable object (data scope), and scope chain

Scope chains: if a variable is not in its scope, it will look for the parent, all the way to the top. The process is as follows:

  • Any scope at the time of execution is implemented by the scope chain
  • When a function is defined, the scope chain at which it is defined is linked to the function object’s [[scope]] property
  • When a function object is called, an active object (that is, an object) is created, and for each function parameter, The active object is named as the named attribute of the active object, and the active object is used as the front end of the scope chain, and the function object’s [[scope]] is added to the scope chain.

You can think about the above text, you can better understand the scope of the function.

Function declaration promotion and variable declaration promotion (as)?

Step 1: Create an executable context (EC) and push it into the current EC stack. The EC contains the following information:

  • Lexical context (= context record items (holding variables, function declarations, and parameters) + external lexical context (function’s [[scope]] property, essence of scope chain))
  • This pointer
  • Variable environment (the same value as the environment record entry, but no longer changing.)

Step 2: Collect function declarations, variable declarations, and parameters in an environment record entry. This process of collection is what is commonly called the nature of the phenomenon of claim ascension. If duplicate identifiers are found, precedence is given to function declarations, parameters, and variable declarations (lower precedence is ignored).

Step 3: Start executing the code. Identifiers that are not present in the environment record entry will be searched for their corresponding values based on the scope chain. The environment record entry may also be modified by the assignment statement.

Step 4: After the function completes, the EC stack is ejected and destroyed.

As described in the following step, claim promotion is the case of collecting functions, variable declarations, and parameters according to the order of precedence of the function, parameter, and variable declarations.

Example:

var a = 1;  
function b() {  
    a = 10;  
    return;  
    function a() {} } b(); console.log(a); // Output 1 because the function declaration is promoted, the actual value in b looks like this: //function b() {  
//    function a() {}; // a = 10; //return;  
//    function a() {}  
// }
Copy the code

Correction: Thank you for your correction on Github
About a question in the blog · Issue #1 · stephenzhao/hexo-theme-damonFunction a(){} should be precompiled first, and then the assignment to a will be performed.

// The correct order should be: //function b() {  
//    function a() {}  
//    a = 10;  
//    return;  
// }
Copy the code


What is a closure, how do you use it, and why do you use it?

So let’s do the same thing up here.

var x = 0;
var foo = {
    x:1,
    bar:function () {
        console.log(this.x);
        var that = this;
        return function () {
           console.log(this.x)
           console.log(that.x)
        }
    }
}


foo.bar()       // 1
foo.bar()()     // this: 0, that: 1
Copy the code

In the above example, ba’r returns an anonymous function that can be called externally: foo.bar()() reads the bar execution context variable object that, which forms a closure.

Okay, so now that we’ve understood the pattern above, let’s explain closures.

Closures are functions that can read variables inside other functions

In the Javascript language, local variables can be read only by subfunctions inside a function, so closures can be understood simply as “functions defined inside a function.”

var x = 0;
var bar:function () {
        var n = 999;
        return function () {
           return n;
        }
    }
var outer = bar();
outer() // 999
Copy the code

USES:

  1. Reads variables inside a function
  2. Keep the values of these variables in memory at all times

Let’s modify the above code

var add;
var bar = function () {
        var n = 999;
        add = function () {
            n += 1;
        }
        return function () {
           returnn; } } var outer = bar(); outer() // 999 add(); outer(); / / 1000Copy the code

N is kept in memory instead of being destroyed after execution of bar(). The anonymous function in bar is assigned to Outer, which causes the anonymous function to remain in memory when Outer is not destroyed. The existence of anonymous functions depends on bar, so bar will not be collected by garbage collection after the call.

The add above also accepts an anonymous function, which is itself a closure, so it can also operate externally on variables inside.

Pay attention to the point

  1. Use with caution because it may leak memory
  2. Closures modify the values of internal variables, so be careful when using closures as common methods on objects. An application of closures, singleton pattern

A singleton pattern is defined to produce a unique instance of a class

Singleton patterns are often encountered in JS, such as var a = {}; It’s actually a single example.

But let’s write a more meaningful singleton:

var singleton = function( fn ){
    var result;
    return function() {returnresult || ( result = fn .apply( this, arguments ) ); }}Copy the code

A little more succinct:

var singleton = (function () {
    var instance;
    return function (object) {
        if(! instance){ instance = new object(); }return instance;
    }
    })();
Copy the code

It’s the middle of the night again, these two days I’m watching the Rio Olympic Games, Lin Dan and Lee Chong Wei’s match is the best I’ve seen this year after the NBA finals final. A great hero needs another great opponent to achieve, thanks to Lin Dan, thanks to Lee Chong Wei the world will remember you. Good night

The next article will explain something about JS object-oriented. Please pay attention to my column “Front-end Grocery store”.