I started to change my job at the end of last year, and it has come to an end until now. I have interviewed many companies intermittently. In retrospect, DURING that time, I was torn by the interviewer’s hand and attacked by the written test questions.

In this article, I plan to make a summary of all kinds of interview questions I have met in job hunting (I will summarize after every interview) and interesting questions I have met in my review. The New Year is the peak period of job-hopping, which may help some friends.

Let’s talk about the difficulty of these questions first, most of them are basic questions, because this experience gives me the feeling that no matter you are interviewing for advanced or elementary level, basic knowledge will be asked, even some depth, so the basic is very important.

I will divide it into several articles according to the type:

Summary of interview: summary of javascript pilot (completed)

Interview Summary: NodeJS pilot Summary (completed)

Summary of interview: Summary of browser-related pilot (completed)

Summary of interview: CSS pilot summary (completed)

Summary of interview: Summary of framework VUE and engineering related aspects pilot (completed)

Summary of interview: Summary of non-technical questions (completed)

I will seize the time to complete the unfinished summary ~

This article is a summary of javascript related topics, the content is a little long, roughly calculated, with nearly 2W words, recommended to read by computer, welcome friends to collect in the first look.

Take a look at the contents first (the long picture is blurry on the phone, click on the picture to see a larger one)

Q: Introduce the prototype chain

Prototype chain this thing, basically is the interview must ask, and not knowledge points are based on prototype chain extension, so we first put the original chain whole understand. Let’s look at a picture that’s very popular on the Internet

function person() {
  this.name = 10
}
person.prototype.age = 10
const p = new person()
Copy the code

Analysis constructor

Let’s look at the contents of the person function through the breakpoint

It is a custom function type. Look at the key two properties: Prototype and __proto__

  1. Analysis of the prototype

Prototype constructor __proto__ (); this object has three attributes: age constructor __proto__ (); Then you can see that the parameters assigned by Person. prototype are in the prototype object.

The value of this property points to the preson () constructor function

So, prototype can literally be translated as the original object for extending properties and methods.

  1. __proto__Analysis of__proto__A look at

The __proto__ attribute in person is the original function Object, and the __proto__ attribute in function Object is the original Object. The __proto__ attribute is found again in Object, with __proto__ equal to null

Js data types are divided into two types, basic type and object type, so we can guess that person is a user-defined function type, which should belong to the family of functions. For functions, we know that they belong to objects, so how are they related?

Yes, through the __proto__ property, and the chain made up of this property is called a prototype chain.

From the above example, we can conclude that the top of the prototype chain is null, and the bottom is Object, and any Object or function type will have the __proto__ attribute. After all, everyone is a member of jS-family.

Analyze the generated objects

Now that we know about prototypes and prototype chains, what is the relationship between new objects? Continue breakpoint analysis

The p object has a __proto__ property, and we already know that it’s a prototype chain, and we can find our ancestors by expanding __proto__, and you can see if that looks familiar here, looking at a picture,

That’s right! P. __proto__ is the prototype of the person function, and this step is the core of new (as we’ll see in the next topic).

So what does the prototype chain look like for instance P? p.__proto__ => {constructor:func}.__proto__ => Object => null

What was the main purpose of the chain originally for instance objects?

  • Implement inheritance: Without the stereotype chain, each object is isolated and has no relation to each other, so the stereotype chain is like a tree trunk, enabling inheritance in the face of the object
  • Property lookup: first searches the current instance object, if not found, then searches along__proto__Up to find
  • Instance type determination: Determines whether this instance belongs to a class of objects

There is, just look at the text of the explanation is still a little inexplicable, to in-depth understanding, or need to start more breakpoint debugging, to quickly straighten out.

If you still don’t understand the prototype chain of instance objects, you can look at the next problem: explaining constructors

Q: What is a constructor?

Constructors are not coded differently from normal functions, as long as they can be called from new.

So what function can’t be a constructor?

Arrow functions cannot be constructors.

New is a syntactic sugar, which is implemented step by step to break down the principle and write a function to simulate new: 0. A custom objectFactory simulates the new syntax sugar. The function can take multiple arguments, but the first argument must be a constructor

  1. Create an empty object obj and allocate memory

  2. Get the constructor from the argument list and point the __proto__ attribute of obj to the constructor’s prototype

  3. Construct with apply and change the current this to point to obj

  4. Returns the result of the constructor’s execution, or the current obj object

function objectFactory() {
  var obj = {},
  Constructor = [].shift.call(arguments);
  obj.__proto__ = Constructor.prototype;
  var ret = Constructor.apply(obj, arguments);
  return typeof ret === 'object' ? ret : obj;
};
function fnf() {
    this.x = 123
}
let a2 = objectFactory(fnf) // Simulate new FNF ()
console.log(a2.x) / / 123
Copy the code

As you can see, it’s not complicated. The key is in the second step, setting up the prototype chain of the object, which is also the core point to create the instance object.

Q: What’s the difference between Typeof and Instanceof

Js data types are divided into two types, one is basic data type, one is object type.

The basic data types are: Number String Boolean Null Undefined BigInt Symbol

Object type: Object is also called a reference type

  1. Typeof (a) type used for return values, including “number”, “string”, “Boolean”, “null”, “function” and “undefined”, “symble”, “object”
let a = 1
let a1 = '1'
let a2 = true
let a3 = null
let a4 = undefined
let a5 = Symbol
let a6 = {}
console.log(typeof(a),typeof(a1),typeof(a2),typeof(a3),typeof(a4),typeof(a5),typeof(a6))
// number string boolean object undefined function object
Copy the code
  1. Instanceof is used to determine if the object is a target instance, according to the prototype chain__proto__Layer by layer, instanceof can also determine whether an instance is an instanceof its parent or ancestor type.

Here’s an interview question

function person() {
    this.name = 10
}
console.log(person instanceof person)
Copy the code

Proto_ => function.proto => object.proto => null, so you can’t find person on the prototype chain

Q: What are the data types?

  • Seven raw data types:Null Undefined String Number Boolean BigInt Symbol
  • Object Object type, also known as reference type

Q: What are the memory differences between basic data types and reference types in JS?

Basic types: Stored in stack memory, because basic types are fixed in size and can be quickly looked up within the stack.

Reference types: stored in heap memory, because the size of reference types is not fixed, so stored in heap memory, and then in stack memory only stored in the heap memory address.

We are looking up objects from the stack, so we know that we operate on the value of the base object, and on the address of the reference type.

var name = 'xiaoming'
var name1 = name; Copy / / value
var obj = {age:10}
var obj1 = obj // A copy of the reference address, so these two objects refer to the same memory address, so they are actually the same object
Copy the code

Are parameters to a function passed by value or by reference?

A lot of people say that primitive types pass values and object types pass references, but strictly speaking, function parameters pass values. As you can see from the above figure, even a reference type stores a string of memory addresses on the stack, so it is also a value. But I don’t think there’s any point in dwelling on it, just understand.

Q: What does NaN refer to

A NaN attribute is a special value that represents a non-numeric value and is used to indicate that a value is not a number.

NaN is a static property in the Number object

typeof(NaN) // "number"
NaN= =NaN // false
Copy the code

So how do you tell if a value is a NAN? For ES6 support, use number.isnan () directly

If not, you can use the NAN! == NAN features

function isReallyNaN(val) {
    let x = Number(val);
    returnx ! == x; }Copy the code

Q: describe a null

Null is one of the basic types, not Object. Why? Answer: historical reason, I also dare not ask

typeof(null) // "object"
null instanceof Object // false
Copy the code

So how do you tell if a value is null? According to the characteristics described above,

function isNull(a) {
    if(! a &&typeof (a) === 'object') {
        return true
    }
    return false
}
console.log(isNull(0))    // false
console.log(isNull(false))// false
console.log(isNull(' '))   // false
console.log(isNull(null)) // true
Copy the code

Q: What is a wrapper object

Wrap an object, as long as it’s easy to call its methods for primitive types.

There are three types of wrapped objects: String Number Boolean

These three primitive types can be converted automatically to instance objects, turning values of primitive types into (wrapped) objects. For example, when a string calls a function, the engine converts values of primitive types into read-only wrapped objects that are destroyed after the function is executed.

Q: What is the difference between class and function

Class is also a syntactic sugar, essentially based on the prototype chain, class semantics and coding is more object-oriented thinking.

Function can use call apply bind to change its execution context, but class cannot. Class is essentially a function, but it has a layer of proxy that prevents this behavior when converted to ES5 (Babel).

  • The method defined in class is not availableObject.keys()traverse
  • Classes cannot define private properties and methods; functions can, as long as they are not mounted in this scope
  • Class can only be called by class name
  • Class. This refers to the class, not the instance

Q: Several ways to implement inheritance

Because more code is involved, so write a separate article to summarize, portal: JS – several ways to implement inheritance

Q: Talk about the scope chain mechanism

Let’s start with the concept of scope. A scope is the accessible scope of a variable or function, controlling the accessible lines and life cycle of that variable or function (this is important).

The scope of your variable function is determined by the position in your code, and can be changed by using the apply bind function.

Before ES6, there were two types of scope in JS: functional scope and global scope.

As the name suggests, the global scope is the browser’s window, the top of the scope chain is it, so as long as the variable or function is not wrapped in a function, its scope is global.

The scope of a function is the variables, functions and parameters declared in the body of the function. Their scope is inside the function. What about variables in a function that are not defined in that function? How do I get this variable? So that’s the concept of scope chains.

We know there is a function at execution time is execution stack, at the time of function creates the execution environment, namely the execution context, in the context of a large object, save execution environment defined variables and functions, at the time of using variables, will visit this large object, the object will create as function call, end function performs the stack and destroyed, Then these large objects form a chain, called a scope chain.

Undefined variables inside the function are searched up the scope chain until they find the property with the same name.

Look at this chestnut down here

var a = 10;
function fn() {
  var b = 20;
  function bar() {
    console.log(a + b) // if (fn =20) {// if (fn =20) {// if (fn =20) {//
  }
  return bar
}
b = 200;
var x = fn();
x()
Copy the code

As long as there is an internal call to a function, the execution stack keeps the scope of the parent function and the function’s pair. Therefore, the scope of the parent function is in the chain of scopes of the child function. The parent function is not released until the child function is destroyed

function test() {
    for (var index = 0; index < 3; index++) {
        setTimeout((a)= > {
            console.log('index:' + index)
        })
    }
}

test() 
// index:3
// index:3
// index:3
Copy the code

The result is 3 3’s, because of the js event loop mechanism, I won’t go into details, so we want it to output in order, what do we do?

Thinking is, because the timer callback must be executed at the end of the cycle, when the index is 3, then you can use the above said the closure of the scope chain in reference to the parent in the sub function variable, like this function has not been destroyed, the variable will always exist, so we can change.

function test() {
    for (var index = 0; index < 3; index++) {
        ((index) = > {
            setTimeout((a)= > {
                console.log('index:' + index)
            })
        })(index)
    }
}
Copy the code

We’re looking at an interview question

function f(fn, x) {
    console.log('into')
    if (x < 1) {
        f(g, 1);
    } else {
        fn();
    }
    function g() {
        console.log('x'+ x); }}function h() {
}

f(h, 0) // x 0
Copy the code

The logic is simple, but that’s how simple interview questions get.

The x variable in g refers to the parent, and the x variable in F is executed twice, which is 0, 1. When f(h,0) is executed, the x in scope of this function is 0, and the x referenced in g is the x=0 variable in the current execution context. F (g, 1), x=1, but notice that the scope of the two f executions is not the same object, but two independent objects in the scope chain, and finally fn(), which is a parameter, So when f(h,0) is executed, the g function, so the g function is executed here, the x printed out by g is 0.

Block-level scope: Let const was invented to solve the problem of js not having block-level scope.

Other small points:

  • Another special feature of the for loop is that the part that sets the variables of the loop is a parent scope, while the inside of the loop body is a separate child scope
  • Variables in a function can be divided into free variables (variables not defined in the current scope) and local scope variables. The value of the free variable depends on the domain in which the function was created (very important), also known as static scope.
  • The difference between scope and execution context takes a look at the two phases of script execution by the engine

Interpretation stage: lexical analysis -> parsing -> scoping rule determination Execution stage: Create execution context -> Execute function code -> garbage collection

Resources: segmentfault.com/a/119000001… www.cnblogs.com/dolphinX/p/…

Q: Let var const

Var: When parsing js, the parser will scan the script and advance the declaration of variables to the top of the code block. The assignment will remain in the original position. If called before the assignment, there will be a temporary dead zone with the value undefined

Let const: does not exist in variable promotion, and the scope exists in the block-level scope, so the occurrence of these two solve the problem of variable promotion, and reference the block-level scope. Note: Variables are promoted to solve the problem of functions calling each other.

Q: The difference between data attributes and accessor attributes

DefineProperty = Object.defineProperty

  1. Data attributes (Data descriptors)

The related attributes are as follows:

[[64x]] : Indicates that the property can be deleted by delete, modified, or modified as an accessor property.

[[Enumerable]] : Returns a property through a for-in loop.

[[Writable]] : indicates whether the value of an attribute can be modified.

[[Value]] : contains the Value of this attribute. When reading property values, read from this position; When writing property values, store the new values in this location. The default value for this feature is undefined.

Data attributes can be defined directly, such as var p = {name:’ XXX ‘}, where the name is the data attribute. If you want to change the default value, use the object.defineProperty () method, as in the following example

var p = {
    name:'dage'
}
Object.defineProperty(p,'name', {value:'xxx'
})
p.name = '4rrr'
console.log(p.name) // 4rrr
Object.defineProperty(p,'name', {writable:false.value:'again'
})
p.name = '4rrr'
console.log(p.name) // again
Copy the code
  • If the Object defineProperty() method does not display any additional values, it defaults to false
  • If the writable is false and the 64x is true, the property can be reconfigured.
  1. Accessor properties (access descriptors)

Accessor attributes do not contain data values, there is no value attribute, there is a get set attribute, through these two attributes to read and write values customized, can be understood as the value and assignment before the interceptor, related attributes are as follows:

[[64x]] : Indicates that the property can be deleted by delete, modified, or changed to a data property. The default is false

[[Enumerable]] : returns a property through a for-in loop. Default is false

[[Get]] : function called when reading properties. The default value is undefined

[[Set]] : function called when writing properties. The default value is undefined

  • The visitor property cannot be defined directly and must be defined using Object.defineProperty().
  • According to theget setCan realize object proxy,vueThis is how data hijacking is implemented.

They both have different properties, different and Enumerable.

A simple little demo

var p = {
    name:' '
}
Object.defineProperty(p,'name', {get:function(){
        return 'right yeah ! '
    },
    set:function(val){
        return 'handsome '+val
    }
})
p.name = `xiaoli`
console.log(p.name) // right yeah !
Copy the code

Reference connection:

Cloud.tencent.com/developer/a…

Developer.mozilla.org/zh-CN/docs/…

Q: What’s the difference between toString and valueOf

These two methods exist in Object, and objects that inherit Object can override methods. These two methods are mainly used for implicit conversions, such as

Js is different from other languages in that two different data types can perform four operations and judgments, thanks to implicit conversions, which I won’t go into detail because I haven’t been asked ~

1 + '1' // 11: Integer 1 is converted to the string '1', which becomes '1' + '1' = '11'
2 * '3' // 6: The string '3' is converted to the integer type 3, which becomes 2 * 3 = 6
Copy the code

We can also override these functions on custom objects for implicit conversions

let o = function () {
    this.toString = (a)= > {
        return 'my is o,'
    }
    this.valueOf = (a)= > {
        return 99}}let n = new o()
console.log(n + 'abc') // 99abc
console.log(n * 10) / / 990
// There is no cool
Copy the code

When these two functions exist together, valueOf is called first, and toString is called if it does not return a primitive type. If toString does not return a primitive type, TypeError is raised: Cannot convert object to Primitive Value as follows

let o = function () {
    this.toString = (a)= > {
        console.log('into toString')
        return { 'string': 'ssss'}}this.valueOf = (a)= > {
        console.log('into valueOf')
        return { 'val': 99}}}let n = new o()
console.log(n + 'xx')
//into valueOf
//into toString
// VM1904:12 Uncaught TypeError: Cannot convert object to primitive value
Copy the code

Q: Does arrow function have arguments objects?

(Thank you very much for reminding us in the comments section)

Arguments is an array-like object that can get an array of arguments and a list of arguments. For functions with undefined arguments, arguments can be retrieved as arguments.

Are there arguments for arrow functions? It depends on the execution scenario

// Arrow function
let aa1 = (. args) = > {
    let bb = [].slice.call(arguments.0)
    let a = arguments[0]
    let b = arguments[1]
    let c = arguments[2]
    console.log(a + b + c)
}

// Normal function
let aa = function (. args) {
    let bb = [].slice.call(arguments.0)
    let a = arguments[0]
    let b = arguments[1]
    let c = arguments[2]
    console.log(a + b + c)
}
aa(1.2.3)
aa1(1.2.3)
Copy the code

Observe the execution results of the following two scenarios

Execute in browser

Go straight to the results

Arguments obviously don’t exist in browsers

Nodejs performed in

Result (preceded by a string for identification)

Arguments () {return “6”;}

Let’s look at the arrow function break point

The arguments object looks fine, as well as the arguments passed in

Let’s look at the values we get from arrays

These are the modules that the script is currently executing, not the list of parameters we expected

conclusion

  1. The arrow function does not exist in the browserarguments
  2. In NodeJS, there arearguments, can get the parameter length, but cannot get the parameter list by changing the object

(I don’t quite understand the principle of this object, please let me know in the comment section if you know, thank you)

Q: JS precision loss problem

Floating-point precision loss isn’t just a matter of js, Java will precision leakage problems (no black Java), mainly because the values in memory consists of binary storage, and certain values can appear when converted into binary infinite loop, because digits limit, the value of the infinite loop will adopt “rounding method” interception, Become a computer that is close to the number inside, even if it is close, but the error has already appeared.

Take a chestnut

0.1 + 0.2  = 0.30000000000000004
// 0.1 to binary will loop indefinitely
/ / "0.000110011001100110011001100110011001100110011001100..."
Copy the code

So how do you avoid this problem? Solution: before the operation, magnify a certain multiple, and then divide by the same multiple

(0.1 *100 + 0.2*100) / 100 = 0.3
Copy the code

The largest integer that can be accurately represented in JS is math.pow (2, 53).

Recommend an open source tool (number-Precision)[github.com/nefe/number…]

Q: Can toFixed be rounded

ToFixed is fine for rounding up to six, but very weird for mantissa of five

(1.235).toFixed(2) / / "1.24" is correct
(1.355).toFixed(2)   / / "1.35" error
Copy the code

I don’t know why it’s designed this way, but strict rounding can use the following function

// Use math. round to round the array to a certain number of times
function round(number, precision) {
    return Math.round(+number + 'e' + precision) / Math.pow(10, precision);
}
Copy the code

The principle is that math.round can be rounded, but only to positive integers, so we can zoom in to save one decimal place, and then zoom out when we’re done.

Q: How to convert different bases in JS

Number(val).tostring ([2,8,10,16])

ParseInt (“1101110”,[2,8,10,16])

Interconversion of other bases: first convert other bases to base 10, and then convert base 10 to other bases

Q: Do you know anything about JS processing binary

ArrayBuffer: Used to represent a generic, fixed-length buffer of raw binary data. As an area of memory, it can hold multiple types of data. It cannot be read or written directly, but only through views.

In the same memory, different data can be interpreted in different ways. This is called a view, and the view is used to interpret binary data in a specified format. There are currently two types of views, TypedArray view and DataView. The difference between the two is mainly the byte order, the former array members are the same data type, the latter array members can be different data types.

Blob: Also holds the binary container, through FileReader conversion.

Nodejs binary vs. Buffer

After all, the application of this relatively little, I recommend an article for you binary array

Q: What are the solutions for asynchrony

This question has a high attendance rate! The common ones are as follows:

  • The callback function: implemented through nested calls
  • Generator: container for asynchronous tasks. Generators are essentially special iterators. After execution, Generator returns a pointer object, and calls the next function in the object to move the internal pointer and execute in stagesGeneratorFunction, pointing toyieldStatement, return an object {value: current execution result, done: finished or not}
  • promisePromise is a new syntactic sugar. The biggest problem with Promise is code redundancy, passing execution rights through THEN. Because you need to call THEN methods manually, when there are many asynchronous functions, the original semantics become unclear
  • co: Encapsulates Generator and Promise to achieve automatic execution
  • async\await: It is currently es7 draft and can be adoptedbable webpackTools such as early use, the current native browser support is not very good. It’s essentially syntactic sugar, and like co libraries, it’s all rightgenerator+promiseHowever, compared with CO, it has better semantics, can be called like ordinary functions, and large probability is the trend of the future.

Q: Briefly introduce the Generator

A Generator function is a encapsulated asynchronous task, or a container for asynchronous tasks.

At the heart of the Generator is the ability to suspend function execution and then resume execution from where it was last paused, identified by the yield keyword.

The Generator function returns an iterator object that does not immediately execute the methods in the function. The object contains the next() function, which returns value and done. The value attribute indicates the value of the current internal state, and the done attribute indicates whether the function is finished or not.

Each step of the Generator is executed by calling the next() function, which can take an argument that is treated as the return value of the previous yield expression. The steps are as follows:

(1) When a yield expression is encountered, the following operation is paused and the value immediately following the yield expression is used as the value of the returned object’s value property.

(2) The next time the next method is called, the execution continues until the next yield expression is encountered.

(3) If no new yield expression is encountered, the function is run until the end of the return statement, and the value of the expression following the return statement is used as the value of the returned object’s value property.

(4) If the function does not have a return statement, the value attribute of the returned object is undefined. Note that the yield expression, which itself has no value, needs to be passed in as an argument to the next() function.

let go = function* (x) {
    console.log('one', x)
    let a = yield x * 2
    console.log('two', a)
    let b = yield x + 1
    sum = a + b
    return sum
}
let g = go(10)
let val = g.next()
while(! val.done) { val = g.next(val.value) }console.log(val)
Copy the code

The disadvantages of Generator are obvious. It is not convenient to perform flow management, and the value returned asynchronously needs to be passed manually.

Q: Tell me about Promise

Promise is already an ES6 specification and is designed to be more reasonable and convenient than Generator.

Take a look at the Promise specification:

  1. The current state of a Promise must be one of the following three states: Pending, Fulfilled and Rejected. The change of the state can only be one-way and cannot be changed after the change.
  2. A Promise must provide a THEN method to access its current value, final value, and reason. The promise. Then (onFulfilled, onRejected) callback function can only be executed once and returns the Promise object

Each operation of a PROMISE returns a Promise object, which supports chained invocation. The callback function is executed through the THEN method, and Promise’s callback is a microqueue placed in an event loop.

Q: Execution principle of the CO library

Co uses the promise feature to wrap the Generator in the promise, and then executes the next function in a loop, wrapping the value returned by the next function in the promise. The next next function is called via then.resolve, passing the value to the next function until done is true, and finally resolve, which wraps the Generator function, is executed.

Let’s look at the source code, the source code has been taken

function co(gen) {
    return new Promise(function(resolve, reject) { // The outermost layer is a Promise object
      if (typeof gen === 'function') gen = gen.apply(ctx, args);
      if(! gen ||typeofgen.next ! = ='function') return resolve(gen);
  
      onFulfilled();
  
      function onFulfilled(res) {
        var ret;
        try {
          ret = gen.next(res); // Pass the return value from the previous step to next
        } catch (e) {
          return reject(e);
        }
        next(ret); // Convert the result of the previous execution to a promise
        return null;
      }
  
      /** * Get the next value in the generator, * return a promise. * * @param {Object} ret * @return {Promise} * @api private */
  
      function next(ret) {
        if (ret.done) return resolve(ret.value); // If done is true, the execution is complete and the resolve result is resolved
        var value = toPromise.call(ctx, ret.value); // toPromise is a utility function that converts an object to a promise
        if (value && isPromise(value)) return value.then(onFulfilled, onRejected); // Then performs the ondepressing callback
        return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' // Exception handling
          + 'but the following object was passed: "' + String(ret.value) + '"')); }}); }Copy the code

Q: This section describes the event loop of the browser

This is a must test, my friends, this can read an article I wrote before, portal: JS event loop

Q: This section describes the modular solution

This is a bit much, as you can see in my previous summary, Portal: The interviewer asked me to explain front-end modularity

Q: Garbage collection mechanism

Why garbage collection is needed: Because objects take up memory, and memory resources are limited.

Js periodically destroys objects that are not in use and frees memory. The key is how to identify which objects are garbage.

Garbage objects: Objects that are not referenced, or objects that form circular references but cannot be accessed by the root, are recyclable garbage.

There are two mechanisms for garbage collection: tag scavenging and reference counting

Mark clearance

Garbage collector at run time will add tags to all variables stored in the memory, then, it will remove the variables and the environment is the environment variables within quotation marks, and after that be add tag variables will be deemed to be ready to remove, the reason is that the environment has been unable to access to the variables in the variables.

At last. The garbage collector does a memory cleanup, destroying the tagged values and reclaiming the memory they occupy.

For example, if you declare a variable in a function, you mark it. When the function completes and exits the stack, the variable’s mark becomes used up.

This is the strategy currently used by major browsers

Reference counting

Track how many times each value is referenced. Once a variable is declared, it is incremented each time it is referenced by another variable. If the variable reference is released, it is decremented by 1. But this has the downside of circular reference, so it’s used less often.

Performance optimization for garbage collection

  1. Generation recycling, the object is divided into two groups, the new belt, the old belt,
  2. The incremental recovery
  3. Idle time recovery

Coding can be optimized

  1. Avoid creating objects repeatedly.
  2. Dereferencing when appropriate is an important way to achieve better performance for your pages.
  3. Global variables can be difficult to determine when they need to automatically free memory, so avoid using them as much as possible during development.

Q: What is strict mode

By putting a specific statement “use strict” at the top of the script; The entire script can turn on strict mode syntax.

Strict mode has the following benefits:

  1. Eliminate some unreasonable and inaccurate Javascript syntax, reduce some weird behavior;
  2. Eliminate some unsafe code operation, to ensure the safety of code operation;
  3. Improve the efficiency of the compiler, increase the running speed;
  4. Set the stage for future versions of Javascript.

Such as the following specific scenarios:

  1. Strict mode will cause assignment operations that silently fail to throw exceptions
  2. Eval in strict mode no longer introduces new variables into the surrounding scope
  3. Strict mode disallows deletion of declared variables
  4. Some characters become reserved keywords in strict mode. These characters include implements, interface, let, package, private, protected, public, static, and yield. In strict mode, you can no longer use these names as variable names or parameter names.
  5. Arguments and parameter values are completely independent in strict mode; non-strict changes can affect each other

Q: Difference between map and weekMap

The key of a map can be of any type. In the map, there are two arrays containing the key and value respectively. Subscripts are used to ensure that the two arrays correspond one by one. The recycle algorithm cannot recycle, which may result in memory leaks.

In contrast, WeakMap’s key value must be an object and hold a weak reference to each key object, which means garbage collection works correctly when no other reference exists.

const wm1 = new WeakMap(a);const o1 = {};
wm1.set(o1, 37);  // When the O1 object is reclaimed, the value in WeakMap is released
Copy the code

Q: What are the common functions of String and Array

I don’t know why they even have them…

  1. String:

Split (): The method splits a String into an array of substrings using the specified delimiter String

Slice (): Method extracts a portion of a string and returns a new string, leaving the original string unchanged

Substring (): Method returns a subset of a string from the start index to the end index, or from the start index to the end of the string

  1. Array:

Slice (): the slice() method returns a new array object that is a shallow copy of the array determined by begin and end (begin, but not end). The original array will not be changed.

Splice (): the splice() method modifies an array by deleting or replacing existing elements or adding new ones in place and returns the modified contents as an array. This method changes the original array.

Push (): method adds one or more elements to the end of an array and returns the array’s new length.

Pop (): method removes the last element from the array and returns the value of that element. This method changes the length of the array.

Shift (): removes the first element from the array and returns the value of that element. This method changes the length of the array.

Unshift (): The method adds one or more elements to the beginning of an array and returns the new length of the array (this method modifies the original array).

Q: Several ways to determine arrays

This problem is mainly about understanding the prototype chain

  1. Array.isArray() ES6 api
  2. obj instanceof ArrayPrototype chain search
  3. obj.constructor === ArrayConstructor type judgment
  4. Object.prototype.toString.call(obj) === '[object Array]'ToString returns a string representing the object, which is returned by default if the method is not overridden"[object type]", includingtypeIs the type of the object. This method is recommended if you need to determine the type accurately

Q: There are several ways to loop, whether interrupt is supported and async/await is supported by default

  • For supports interrupts and asynchronous events
  • For of Supports interrupt and asynchronous events
  • For in Supports interrupts and asynchronous events
  • ForEach does not support interrupts and does not support asynchronous events
  • Map does not support interrupts, asynchronous events, and asynchronous processing: Map returns a Promise array, which is processed together with promise. all
  • Reduce does not support interrupts or asynchronous events, and supports asynchronous processing methods: Return value Returns a PROMISE object

I will not write map, I will write reduce processing async/await demo

const sleep = time= > new Promise(res= > setTimeout(res, time))
async function ff(){
    let aa = [1.2.3]
    let pp = await aa.reduce(async (re,val)=>{
        let r = await re;
        await sleep(3000)
        r += val;
        return Promise.resolve(r)
    },Promise.resolve(0))
    console.log(pp) / / 6
}
ff()
Copy the code

Q: Examples of closure usage scenarios

Closure: A function defined inside a function that holds references to variables inside an external function. This internal function has its own execution scope to avoid external contamination.

Closures are a thousand Hamlets for every thousand readers, so find the one that suits your understanding and narration.

Scenarios are:

  1. Functional programming, compose Curry
  2. Function factory, simple interest
  3. Private variables and methods, object-oriented programming

Q: extended operator

The interviewer wants to know if you’ve actually used an ES6 before

Extended operators (…) The default Iterator interface is also called.

Extended operators are used mainly for indeterminate arguments, which can be converted to an array

function fn(. arg){
    console.log(arg) // [1, 2, 3]
}
fn(1.2.3)
Copy the code

Q: What are threads and processes

Both processes and threads are descriptions of a period of time in which the CPU works.

When a task gets CPU resources, it needs to load the execution environment required by the task, also called context. Process is the total execution time of the program including context switch = CPU loading context + CPU execution + CPU saving context. You can see that the process is too granular, requiring context to call in, save, and call out every time.

If we compare the process to A software running on the computer, then the execution of A software can not be A logical execution, there must be multiple branches and multiple program segments, just like to realize the program A, actually divided into A, B, C and other blocks.

So the specific execution here is: program A gets the CPU => CPU load context => start executing A segment of program A => then execute B segment of program A => then execute C segment of program A => Finally, the CPU saves A context. Here, the execution of A, B, and C shares the context of A, and the CPU does not switch the context during the execution.

A, B, and C are what we call threads, which means threads share the context of the process and are smaller CPU execution times.

Q: Do you know functional programming

The two cores of functional programming, composition and Currification, were summarized earlier, portal: [Interviewer asked] Do you know functional programming?

Q: What is tail recursion?

Give the interviewer simply what is a recursive function: a function calls itself inner loop is a recursive function, if the function is not complete, will remain in the execution stack function related variables, memory, when the recursion number is too large, it may be out of memory, also called the stack, the page is likely to be stuck. So to avoid this, tail recursion can be used.

Tail recursion: The last step of a function is to call the function and enter the environment where the next function no longer needs the previous function. The optimization of the memory space O(n) to O(1) is called tail recursion. Benefits of tail recursion: it can release the call stack of outer functions, reducing the stack level, saving memory overhead and avoiding memory overflow.

A lot of people on the Internet use Fibonacci sequences for chestnuts, but I don’t. I use an array summation chestnut

function add1(arr) {
    if (arr.length === 0) {
        return 0
    }
    return add1(arr.slice(1)) + arr[0] // There is a reference to arr[0] in the parent function
}

function add(arr, re) {
    if (arr.length === 0) {
        return re + 0
    } else {
        return add(arr.slice(1), arr[0] + re) // Just a function call}}console.log(add([1.2.3.4].0))  / / 10
console.log(add1([1.2.3.4])) / / 10
Copy the code

Q: The difference between the observer publish-subscribe model

Both are subscription-notification models, the differences being:

The Observer pattern: The observer and the subscriber know each other, and it is a tightly coupled design

Publisk-subscribe: Observers and subscribers are unaware of each other because they interact through a subscription center that stores multiple subscribers and notifys them of new releases

There are a lot of names for design patterns, so let me draw a simple picture:

Q:WebSocket

I only asked this once, so I simply understood it.

In simple terms, WebSocket is an application layer protocol based on TCP and located at the application layer like HTTP, both of which are subsets of TCP/IP.

HTTP is a one-way communication protocol. The server returns data only when the client initiates an HTTP request. The WebSocket protocol is a two-way communication protocol. After the connection is established, both the client and the server can actively send or receive data to each other.

Reference data: www.ruanyifeng.com/blog/2017/0…

The last

The above is a summary of javascript related topics, and we will continue to add some representative topics.

If there is something wrong in the article, you are welcome to correct it.

Thank you.