With companies downsizing or even downsizing during the dotcom winter, getting a better job requires more effort.

A year ago, you might have been recognized for figuring out the closure, this, the prototype chain. But now, apparently not. In this article, we’ve sorted out some of the most difficult and frequent native JS questions that you may have never looked at before, or seen before, but haven’t studied carefully, but they are very important.

This article will be presented in the form of real interview questions. As you read, you are advised not to read my answers first, but to think about them for yourself. Although, all the answers in this article are given by me after browsing through various materials, thinking and verifying (by no means copy and paste). However, due to the limited level, my answer may not be the best, if you have a better answer, welcome to leave a message to me.

This article is long, but full of dry stuff! There are also cute memes waiting for you to finish reading.

I sincerely wish you all can find your dream job.

More articles can be read: github.com/YvetteLau/B…

1. What are the basic types? Is NULL an object? What is the difference between primitive data type and complex data type storage?

  • There are six basic types, respectively is Undefined, Null, Boolean, String, Number, Symbol (new) ES6. In addition, ES10 added a BigInt data type
  • Although typeof NULL returns a value of Object, NULL is not an object, but one of the basic data types.
  • The basic data types are stored in stack memory, and the values are stored.
  • Values for complex data types are stored in heap memory, and addresses (pointing to values in the heap) are stored in stack memory. When we assign an object to another variable, we copy the address, pointing to the same block of memory, and when one object changes, the other object changes.

2. Check whether typeof correctly determines the type. Instanceof? How does Instanceof work?

First, TypeOF correctly identifies basic data types, but instead of null, Typeof NULL outputs objects.

However, for objects, typeof does not correctly determine its type. A typeof function can output ‘function’, but other than that, output is all object. In this case, we cannot accurately know the typeof the object.

Instanceof can accurately determine complex data types, but not basic data types. (Please check github.com/YvetteLau/B…)

Instanceof is judged by the prototype chain. A instanceof B is searched layer by layer in the prototype chain of A to see if there is A prototype equal to B. Prototype. If the top of the prototype chain of A is always found (null; Object. Proptotype.__proto__), still not equal to b. prototype, then return false, otherwise return true.

Instanceof implementation code:

function instance_of(L, R) {//L represents the left expression, R represents the right expression
    let prototype = R.prototype;
    while (true) {
        if(L === null) {// The top of the prototype chain has been found
            return false;
        } else if(L.__proto__ === prototype) {
            return true;
        } 
        L = L.__proto__;// Continue up the prototype chain}}Copy the code

3. For of, for in and forEach,map

  • for… Of loop: With an iterator interface, you can use for… The of loop iterates through its members (attribute values). for… The scope for the OF loop includes arrays, Set and Map structures, some array-like objects, Generator objects, and strings. for… The of loop calls the traverser interface, which returns only properties with numeric indexes. For ordinary objects, for… The of structure cannot be used directly because an error is reported. You must deploy the Iterator interface to use it. You can break the loop.
  • for… In loop: Iterates over an object’s own and inherited enumerable properties without directly fetching the property value. You can break the loop.
  • ForEach: the array can only be traversed without interruption, with no return value (or assumed to be undefined).
  • Map: The array can only be traversed without interruption, and the return value is the modified array.

PS: object.keys () : Returns an array of strings containing all the enumerable properties of a given Object.

I wrote some code to test whether forEach would change the array (note that the array items are complex data types). In addition to forEach, apis like Map have the same problem.

let arry = [1.2.3.4];

arry.forEach((item) = > {
    item *= 10;
});
console.log(arry); / / [1, 2, 3, 4]

arry.forEach((item) = > {
    arry[1] = 10; // Manipulate arrays directly
});
console.log(arry); //[1, 10, 3, 4]

let arry2 = [
    { name: "Yve" },
    { age: 20}]; arry2.forEach((item) = > {
    item.name = 10;
});
console.log(arry2);//[ { name: 10 }, { age: 20, name: 10 } ]
Copy the code

If you don’t know the Iterator interface or for… Of, read the ES6 documentation: Iterator and for… Of circulation

For more details: github.com/YvetteLau/B…


4. How to determine if a variable is an array?

  • Use array. isArray. If true is returned, it is an Array
  • Check with instanceof Array. If true, it is an Array
  • Use Object. The prototype. ToString. Call judgment, if the value is [Object Array], that is an Array
  • Constructor if it is an array, thenarr.constructor === ArrayNot exact, because we can specifyobj.constructor = Array)
function fn() {
    console.log(Array.isArray(arguments));   //false; Arguments is an array of classes, but not an array
    console.log(Array.isArray([1.2.3.4]));   //true
    console.log(arguments instanceof Array); //fasle
    console.log([1.2.3.4] instanceof Array); //true
    console.log(Object.prototype.toString.call(arguments)); //[object Arguments]
    console.log(Object.prototype.toString.call([1.2.3.4])); //[object Array]
    console.log(arguments.constructor === Array); //false
    arguments.constructor = Array;
    console.log(arguments.constructor === Array); //true
    console.log(Array.isArray(arguments));        //false
}
fn(1.2.3.4);
Copy the code

5. What is the difference between a class array and an array?

Class array:

1) Has the length attribute and other attributes (indexes) are non-negative integers (indexes in objects are treated as strings);

2) Does not have array methods;

A class Array is a normal object, whereas a real Array is of type Array.

Common class array are: the parameters of the function arguments, DOM object list (such as through the document. QuerySelectorAll get list), the jQuery object ($(” div “), for example).

Class arrays can be converted to arrays:

// The first method
Array.prototype.slice.call(arrayLike, start);
// The second method
[...arrayLike];
// Third method:
Array.from(arrayLike);
Copy the code

PS: Any object that defines an Iterator interface can be converted to a true array using the extension operator.

The array. from method is used to convert two types of objects into true arrays: array-like objects and iterable objects.


6. What’s the difference between == and ==?

=== No type conversion is required and true is returned only if the types are the same and the values are equal.

== If the two types are different, type conversion is required first. The specific process is as follows:

  1. First, check whether the two types are the same. If they are equal, check whether the values are equal.
  2. If the type is different, cast it
  3. Checks whether the comparison is null or undefined, and returns true if so.
  4. Check whether the two types are string and number, and if so, convert the string to number
  5. Check whether one of the parties is Boolean. If so, convert the Boolean to number
  6. Determine if one is object and the other is string, number, or symbol. If so, convert object to its original type
let person1 = {
    age: 25
}
let person2 = person1;
person2.gae = 20;
console.log(person1 === person2); //true, note complex data types, compare reference addresses
Copy the code

Think about:[] = =! []

Let’s analyze: [] ==! [] is true or false?

  1. First, we need to know! Precedence is higher than == (More operator precedence can be seen: operator precedence)
  2. ! []All conversions to booleans are true, so! []Is false
  3. According to the fifth comparison step above, one of the parties is Boolean, convert Boolean to number and then judge, false is converted to number and the corresponding value is 0.
  4. If there is a number on one side, convert object to number and an empty array to a number with the value 0. If there is only one number in the array, convert number to that number. Otherwise, it is NaN.
  5. 0 = = 0; To true

7. What is the difference between ES6 classes and ES5 classes?

  1. All methods defined within an ES6 class are non-enumerable;
  2. ES6 classes must be called with new;
  3. ES6 class does not have variable promotion;
  4. ES6 classes default to strict mode;
  5. The ES6 class subclass must call super() in the constructor to have this object; In ES5, the class inheritance relationship is reversed. We subclass this and then apply the superclass methods to this.

8. Which API of an array changes the original array?

The API for modifying the original array is:

splice/reverse/fill/copyWithin/sort/push/pop/unshift/shift

Apis that do not modify the original array are:

slice/map/forEach/every/filter/reduce/entries/find

Note: Each entry in an array is a simple data type and does not operate directly on the array (this question will be recap later).


9. What is the difference between let, const, and var?

  • Variables defined by let and const do not get promoted, whereas variables defined by var do.
  • Let and const are block-level scopes in JS
  • Let and const are not allowed to be declared twice (throws an error)
  • Variables defined by let and const throw an error if used before the statement is defined (creating a temporary dead zone), whereas var does not.
  • Const declares a read-only constant. Once declared, the value of a constant cannot be changed (if the declaration is an object, then the reference address of the object cannot be changed).

10. What is variable promotion in JS? What is a temporary dead zone?

Variable promotion is when a variable can be used before it is declared, with the value undefined.

A variable is unavailable (throwing an error) within a code block until it is declared using the let/const command. This is grammatically called a “temporary dead zone”. Temporary dead zones also mean that Typeof is no longer a 100% safe operation.

typeof x; // ReferenceError(temporary dead zone, throw error)
let x;
Copy the code
typeof y; // The value is undefined
Copy the code

The essence of a temporary dead zone is that the variable you want to use already exists as soon as you enter the current scope, but you can’t get it until the line of code that declared the variable appears.


11. How to judge this correctly? What is this of the arrow function?

There are four binding rules for this: default binding, implicit binding, explicit binding, and new binding.

  1. Whether the function is called in new (new binding), and if so, this is bound to the newly created object in new.
  2. Whether the function is called by call,apply, or by using bind, if so, this binds to the specified object.
  3. Whether the function is called in a context object (implicitly bound), and if so, this binds to that context object. Usually obj. Foo ()
  4. If none of the above, use the default binding. If in strict mode, it is bound to undefined, otherwise to a global object.
  5. If null or undefined is passed to call, apply, or bind as a binding object for this, these values will be ignored during the call and the default binding rules will apply.
  6. The arrow function does not have its own this; its this inherits from the this of the previous code block.

Test whether the knowledge has been successfully Get (browser execution environment):

var number = 5;
var obj = {
    number: 3.fn1: (function () {
        var number;
        this.number *= 2;
        number = number * 2;
        number = 3;
        return function () {
            var num = this.number;
            this.number *= 2;
            console.log(num);
            number *= 3;
            console.log(number); }}}) ()var fn1 = obj.fn1;
fn1.call(null);
obj.fn1();
console.log(window.number);
Copy the code

Hi, do you really understand this?


12. Lexical scope and this.

  • The lexical scope is determined by where you put the variable and block scope when you write the code, right
  • This is bound when the function is called. What this refers to depends entirely on where the function is called.

13. Talk about your understanding of JS execution context stacks and scope chains.

The execution context is the environment where the current JavaScript code is parsed and executed. The JS execution context stack can be considered as a stack structure storing function calls, following the principle of “first in, last out”.

  • JavaScript executes on a single thread and all code is queued.
  • When the browser executes global code, it first creates the global execution context, pushing it to the top of the execution stack.
  • Each time a function is executed, the execution context of the function is created and pushed to the top of the stack. Current function execution – After completion, the execution context of the current function is removed from the stack and waits for garbage collection.
  • The browser’s JS execution engine always accesses the execution context at the top of the stack.
  • There is only one global context, which is pushed out when the browser closes.

Scope chain: Either LHS or RHS queries start looking at the current scope, and if none is found, the search for the target identifier continues up the chain, one scope at a time, until it reaches the global scope.


How difficult is it? It is not difficult to! Keep up the challenge! Difficult! Know difficult, want to continue more!

What is a closure? What does a closure do? What are the use scenarios for closures?

A closure is a function that has access to variables in the scope of another function, and the most common way to create a closure is to create another function inside a function.

Closures have the following functions:

  1. Encapsulating private variables
  2. Mimicking block-level scopes (no block-level scopes in ES5)
  3. A module that implements JS

15. What’s the difference between call and apply? How are call, Aplly, and Bind implemented internally?

Call and apply have the same function, but the difference is that they pass different parameters:

  • fn.call(obj, arg1, arg2, …) , calls a function with a specified this value and arguments supplied separately (a list of arguments).

  • Fn. apply(obj, [argsArray]), calls a function with a specified this value and arguments supplied as an array (or array-like object).

Call the core:

  • Sets the function as an attribute of the passed argument
  • Execute the function by specifying this to the function and passing in the given argument
  • If no parameter is passed or the parameter is null, the default point is Window/global
  • Delete functions on parameters
Function.prototype.call = function (context) {
    /** If the first argument is passed null or undefined, point to this and point to window/global */
    If the first argument is not null or undefined, it must be an object */
    if(! context) {// Context is null or undefined
        context = typeof window= = ='undefined' ? global : window;
    }
    context.fn = this; // This refers to the current instance of Function.
    let rest = [...arguments].slice(1);// Get parameters other than the object this points to. An empty array slice returns an empty array
    letresult = context.fn(... rest);// Implicitly bound, the current function's this refers to the context.
    delete context.fn;
    return result;
}

// Test the code
var foo = {
    name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
    console.log(this.name);
    console.log(job, age);
}
bar.call(foo, 'programmer'.20);
// Selina programmer 20
bar.call(null.'teacher'.25);
// browser environment: Chirs teacher 25; Node environment: undefined teacher 25

Copy the code

apply:

The implementation of Apply is similar to that of Call, but note that the arguments are different. The second argument to Apply is an array or an array of classes.

Function.prototype.apply = function (context, rest) {
    if(! context) {// Set the default value when context is null or undefined
        context = typeof window= = ='undefined' ? global : window;
    }
    context.fn = this;
    let result;
    if(rest === undefined || rest === null) {
        //undefined or null is not an Iterator and cannot be...
        result = context.fn(rest);
    }else if(typeof rest === 'object') { result = context.fn(... rest); }delete context.fn;
    return result;
}
var foo = {
    name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
    console.log(this.name);
    console.log(job, age);
}
bar.apply(foo, ['programmer'.20]);
// Selina programmer 20
bar.apply(null['teacher'.25]);
// Browser environment: Chirs programmer 20; Node environment: undefined teacher 25
Copy the code

bind

There is one important difference between bind and call/apply. When a function is called by call/apply, it is called directly, but Bind creates a new function. When the new function is called, the first argument to bind() will be this when it runs, and the subsequent sequence of arguments will be passed as its arguments before the arguments passed.

Function.prototype.bind = function(context) {
    if(typeof this! = ="function") {throw new TypeError("not a function");
    }
    let self = this;
    let args = [...arguments].slice(1);
    function Fn() {};
    Fn.prototype = this.prototype;
    let bound = function() {
        let res = [...args, ...arguments]; // concatenate the arguments passed by bind with those passed by the function call
        context = this instanceof Fn ? this : context || this;
        return self.apply(context, res);
    }
    / / prototype chain
    bound.prototype = new Fn();
    return bound;
}

var name = 'Jack';
function person(age, job, gender){
    console.log(this.name , age, job, gender);
}
var Yve = {name : 'Yvette'};
let result = person.bind(Yve, 22.'enginner') ('female');	
Copy the code

16. What is the principle of new? What is the difference between creating an object as new and creating it as a literal?

new:

  1. Create a new object.
  2. The new object will be connected by the implementation [[prototype]].
  3. Properties and methods are added to the object referenced by this. And executes the methods in the constructor.
  4. If the function returns no other object, the new object created is returned, otherwise the result of the constructor’s execution is returned.
function new() {
    let target = {};
    let [constructor.args] = [...argument];
    target.__proto__ = constructor.prototype;
    let res = func.apply(target, args);
    if ((res && typeof res == "object") | |typeof(res) == "function") {
    	return res;
    }
    return target;
}
Copy the code

Literals create objects without calling the Object constructor, which is simpler and performs better.

Creating an Object using new Object() is essentially a method call, which involves traversing the method through the Proto chain, producing the necessary stack information for the method call when it is found, and releasing the stack when the method call is complete, which is not as efficient as the literal method.

When an Object is defined through an Object literal, the Object constructor is not called.


17. What is your understanding of prototyping?

In JavaScript, whenever you define an object (a function is also an object), the object contains predefined properties. Each of these function objects has a Prototype property that points to the function’s prototype object. The advantage of using a prototype object is that all object instances share the properties and methods it contains.


18. What is a prototype chain? What problem does the prototype chain solve?

The main problem of prototype chain is inheritance.

Each object has a prototype object, with __proto__ (pronounced: Dunder Proto) points to its prototype Object, inherits methods and properties from it, and the prototype Object may own the prototype, layer by layer, eventually pointing to null(Object.prototype.__proto__ points to null). This relationship is called the Prototype chain, through which one object can have properties and methods defined in other objects.

Constructor Parent, Parent. Prototype and instance p :(p.__proto__ === Parent. Prototype)


19. The prototype and__proto__What’s the difference?

Prototype is the constructor property.

__proto__ is a per-instance property that has access to the [[prototype]] property.

The instance’s __proto__ and its constructor’s prototype point to the same object.

function Student(name) {
    this.name = name;
}
Student.prototype.setAge = function(){
    this.age=20;
}
let Jack = new Student('jack');
console.log(Jack.__proto__);
//console.log(Object.getPrototypeOf(Jack));;
console.log(Student.prototype);
console.log(Jack.__proto__ === Student.prototype);//true
Copy the code

20. Implement an inheritance using ES5?

Parasitic combinatorial inheritance (the best form of ES5 inheritance)

Parasitic combinatorial inheritance inherits properties by borrowing constructors and inherits methods through a hybrid form of prototype chains.

The superclass constructor is called only once, which is more efficient. Avoid creating unnecessary, redundant attributes on suberType. prototype, while keeping the prototype chain intact.

Therefore, parasitic combinatorial inheritance is the most rational inheritance paradigm for reference types.

function SuperType(name) {
    this.name = name;
    this.colors = ['red'.'blue'.'green'];
}
SuperType.prototype.getName = function () {
    return this.name;
}

function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
// Parasitic combinatorial inheritance
SuberType.prototype = Object.create(SuperType.prototype);
SuberType.prototype.constructor = SuberType;

SuberType.prototype.getAge = function () {
    return this.age;
}

let girl = new SuberType('Yvette'.18);
girl.getName();
Copy the code

Incidentally, the extends Class approach in ES6 compiles to ES5 using Babel, which also uses parasitic combinatorial inheritance.

For other methods of inheritance, see JavaScript Advanced Programming.


21. What is deep copy? What is the difference between a deep copy and a shallow copy?

Shallow copy refers to copying only the first layer object, but when the object’s property is a reference type, the reference is copied, and the reference changes when the value it points to changes.

Deep copy copies variable values. For variables of non-primitive type, recurse to primitive type variables and then copy. The deep-copy object is completely isolated from the original object, and the modification of one object does not affect the other object.

Implementing a deep copy:

function deepClone(obj) { // Recursive copy
    if(obj === null) return null; / / null
    if(obj instanceof RegExp) return new RegExp(obj);
    if(obj instanceof Date) return new Date(obj);
    if(typeofobj ! = ='object') {
        If it is not a complex data type, return it directly
        return obj;
    }
    /** * if obj is an Array, then obj.constructor is [Function: Array] */
    let t = new obj.constructor();
    for(let key in obj) {
        // if obj[key] is a complex data type, recurse
        t[key] = deepClone(obj[key]);
    }
    return t;
}
Copy the code

Can’t bear to watch? Someone else’s question becomes your question

22. What is the difference between anti-shake and throttling? The realization of anti-shake and throttling.

The purpose of both stabilization and throttling is to prevent multiple calls to the function. The difference is that if a user fires the function all the time and the interval is shorter than the set time, the function will only be called once in the case of stabilization, while the function will be called once in the case of throttling.

Debounce: The function is executed only once within n seconds. If the high frequency event is triggered again within n seconds, the time is recalculated

function debounce(func, wait, immediate = true) {
    let timer;
    // Delay execution of the function
    const later = (context, args) = > setTimeout(() = > {
        timer = null;// The countdown is over
        if(! immediate) { func.apply(context, args);// Perform the callback
            context = args = null;
        }
    }, wait);
    let debounced = function (. params) {
        let context = this;
        let args = params;
        if(! timer) { timer = later(context, args);if (immediate) {
                // Execute immediatelyfunc.apply(context, args); }}else {
            clearTimeout(timer);
            The function is called at the end of each wait delay
            timer = later(context, args);
        }
    }
    debounced.cancel = function () {
        clearTimeout(timer);
        timer = null;
    };
    return debounced;
};
Copy the code

Application scenarios of anti-shake:

  • The resize/scroll statistics event is triggered every time
  • Validation of text input (send AJAX request for validation after continuous text input, once validation is fine)

Throttling: The system executes high-frequency events only once in a specified period of time. After you perform these events once, you can perform them twice only after the specified execution period.

//underscore.js
function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if(! options) options = {};var later = function () {
        previous = options.leading === false ? 0 : Date.now() || new Date().getTime();
        timeout = null;
        result = func.apply(context, args);
        if(! timeout) context = args =null;
    };

    var throttled = function () {
        var now = Date.now() || new Date().getTime();
        if(! previous && options.leading ===false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            result = func.apply(context, args);
            if(! timeout) context = args =null;
        } else if(! timeout && options.trailing ! = =false) {
            // Check whether the timer and trailing are set
            timeout = setTimeout(later, remaining);
        }
        return result;
    };

    throttled.cancel = function () {
        clearTimeout(timeout);
        previous = 0;
        timeout = context = args = null;
    };

    return throttled;
};

Copy the code

The application scenarios of function throttling are:

  • DOM element drag and drop implementation (Mousemove)
  • Shooter mouseDown/KeyDown events (only one shot per unit of time)
  • Calculate the distance of mouse movement (Mousemove)
  • Canvas Drawing Board (Mousemove)
  • Search for Associations (KeyUp)
  • Listen for scroll events to determine whether more automatically loads at the bottom of the page. After adding debounce to Scroll, users will only know whether they have reached the bottom of the page after they stop scrolling. If you’re throttle, you’re going to do it every time you scroll

23. Select the maximum value of the array (ES5, ES6)

// ES5
Math.max.apply(null[14.3.77.30]);

// ES6
Math.max(... [14.3.77.30]);

// reduce
[14.3.77.30].reduce((accumulator, currentValue) = >{
    return accumulator = accumulator > currentValue ? accumulator : currentValue
});
Copy the code

24. What are the new features of ES6?

  1. New block-level scope (let,const)
  2. Provides syntactic sugar (class) for defining classes
  3. A new base data type (Symbol)
  4. New destruct assignment of variables
  5. Function parameters allow default values, rest parameters were introduced, and arrow functions were added
  6. New APIS for arrays, such as isArray/FROM/of methods; New array instance methods entries(), keys() and values() are added
  7. Object and array extension operators have been added
  8. New modularity (import/export) in ES6
  9. ES6 added Set and Map data structures
  10. ES6 natively provides a Proxy constructor to generate a Proxy instance
  11. New generators and Iterators in ES6

25. Why does setTimeout countdown have errors?

SetTimeout () simply inserts the event into the “task queue” and must wait for the current code (execution stack) to finish before the main thread executes its specified callback function. If the current code is taking a long time, it may wait a long time, so there is no guarantee that the callback will execute at setTimeout(). Therefore, the second parameter of setTimeout() indicates the minimum time, not the exact time.

The HTML5 standard states that the second argument to setTimeout() must be at least 4 milliseconds, and if it is less than that, the default is 4 milliseconds. Before that. Older browsers set the minimum time to 10 milliseconds. In addition, DOM changes, especially those involving page re-rendering, are usually performed at 16-millisecond intervals. RequestAnimationFrame () works better than setTimeout();


26. Why 0.1 + 0.2! = 0.3?

0.1 + 0.2! = 0.3 is due to the loss of accuracy in the process of base conversion and advanced operation.

Here are the details:

JavaScript uses the Number type to represent numbers (integers and floating-point numbers) and 64-bit to represent a Number.


Photo caption:

  • Bit 0: sign bit, 0 for a positive number and 1 for a negative number (s).
  • Places 1 to 11: Storage index segment (e)
  • Bits 12 to 63: Store the decimal part (that is, the significant number) f

Computers cannot directly perform operations on decimal numbers. They need to convert them to binary in accordance with IEEE 754 specifications, and then perform operations on order.

1. Base conversion

0.1 and 0.2 will loop indefinitely when converted to binary

0.1 - > 0.0001100110011001... (Infinite loop) 0.2 -> 0.0011001100110011... (Infinite loop)Copy the code

However, due to the LIMITATION of mantras in IEEE 754, redundant bits need to be truncated, so that accuracy is lost in conversion between bases.

2. Logarithmic operation

As the number of digits of exponents are different, precision loss may also occur in the part of order operation.

Following the above two steps (including the accuracy loss of the two steps), the final result is

0.0100110011001100110011001100110011001100110011001100

The result in decimal is 0.30000000000000004.

27. There are several states of promise. What are the advantages and disadvantages of promise?

Promise has three states: depressing, Rejected and pending.

Advantages of Promises:

  1. Once the state changes, it never changes again, and you can get this result at any time
  2. Asynchronous operations can be expressed as a flow of synchronous operations, avoiding layers of nested callback functions

Disadvantages of Promises:

  1. Unable to cancel Promise
  2. When you are in a pending state, you cannot tell what stage you are currently in

28. Is the Promise constructor executed synchronously or asynchronously, and what about the methods in THEN? How does promise implement then processing?

The Promise constructor is executed synchronously. Methods in THEN are executed asynchronously.

Then implementation of promise, see: Promise source code implementation


29. What is the difference between Promise and setTimeout?

Promise is a microtask, setTimeout is a macro task, and in the same event loop, promise.then always precedes setTimeout.


30. How to fulfill promise.all?

To implement Promise.all, first we need to know what promise. all does:

  1. If the argument passed in is an empty iterable, then the promise callback completes (resolve), and only then, is executed synchronously; all else is returned asynchronously.
  2. If the parameters passed in do not contain any promises, an asynchronous completion is returned.

Promises all promises in Promises are “done” or callback done when parameters do not contain promises. 3. If one of the arguments fails, the promise object returned by promise.all fails. In any case, promise.all returns an array as the result of the completion state of the Promise

Promise.all = function (promises) {
    return new Promise((resolve, reject) = > {
        let index = 0;
        let result = [];
        if (promises.length === 0) {
            resolve(result);
        } else {
            function processValue(i, data) {
                result[i] = data;
                if(++index === promises.length) { resolve(result); }}for (let i = 0; i < promises.length; i++) {
                // Promises [I] promises are promises
                Promise.resolve(promises[i]).then((data) = > {
                    processValue(i, data);
                }, (err) = > {
                    reject(err);
                    return; }); }}}); }Copy the code

If you want to learn more about the source implementation of Promise, check out my other article: The source implementation of Promise (perfect for the Promise/A+ specification)


31. How to realize the Promise. Prototype. Finally?

Success or failure will always go to finally, and after finally, can continue then. And passes the value exactly as it should to the subsequent then.

Promise.prototype.finally = function (callback) {
    return this.then((value) = > {
        return Promise.resolve(callback()).then(() = > {
            return value;
        });
    }, (err) = > {
        return Promise.resolve(callback()).then(() = > {
            throw err;
        });
    });
}
Copy the code

32. What is a function Coriolization? Sum (1)(2)(3) returns the sum of 1,2, and 3

Function corrification is the technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function) and returns a new function that takes the remaining arguments and returns the result.

function sum(a) {
    return function(b) {
        return function(c) {
            returna+b+c; }}}console.log(sum(1) (2) (3)); / / 6
Copy the code

Implement a curry function to curryize a common function:

function curry(fn, args = []) {
    return function(){
        let rest = [...args, ...arguments];
        if (rest.length < fn.length) {
            return curry.call(this,fn,rest);
        }else{
            return fn.apply(this,rest); }}}//test
function sum(a,b,c) {
    return a+b+c;
}
let sumFn = curry(sum);
console.log(sumFn(1) (2) (3)); / / 6
console.log(sumFn(1) (2.3)); / / 6
Copy the code

If you encounter more native JS questions in the interview, or have some difficult JS knowledge not covered in this article, please leave me a comment. Your questions will come up in a follow-up article

It took a lot of time to write this article, and I have learned a lot in the process. Thank you for your precious time to read this article. If this article gives you some help or inspiration, please don’t be too generous with your praise and Star, because your praise is definitely the biggest motivation for me to move forward. Github.com/YvetteLau/B…

Follow-up writing plan

1. Native JS: What You Need to Know (Middle)(second)

2. CSS you Need to Know

3. The End of the Road

4. What you Need to Know about Browsers this Job Search Season

5. What You Need to Know

React Stack:

1. The React Series

2. The ReactNative Series: What You Need to Know During The Winter Job Search Season

Reference article:

  1. www.ibm.com/developerwo…
  2. Juejin. Cn/post / 684490…
  3. Selected part of the interview questions on the way to interview
  4. Selected wood yi Yang said the article mentioned part of the interview questions: juejin.cn/post/684490…
  5. Special instructions: 0.1 + 0.2! = = 0.3The answer to this question uses a lot of the text of the article:Juejin. Cn/post / 684490…
  6. Selected some interview questions encountered by friends when interviewing big factories
  7. JavaSctipt you Don’t Know
  8. JavaScript Advanced Programming
  9. Github.com/hanzichi/un…

Follow the public account of “little sister”