The native JS you must understand during the winter job-hunting season (part one)

  Front end, javascript, node.js, Programmer

In the cold winter of the Internet, major companies have reduced HC and even adopted “layoff” measures. Under such a big environment, it is necessary to make more efforts to get a better job.

A year ago, perhaps you could get approval by figuring out closure, this, prototype chain. But now, obviously not. This article sorts out some high-frequency native JS problems that have certain difficulties in interviews. Some knowledge points may have never been noticed before, or you may have seen them but have not studied them carefully, but they are very important. This article will present knowledge points in the form of real face-to-face questions. When reading, we suggest not to look at my answers first, but to think about them first. Although, all the answers in this article were given only after I read all kinds of materials, thought and verified (It is by no means copied and pasted.)。 However, due to limited level, my answer is not necessarily the best. If you have a better answer, please leave me a message.

This article is long, but it is full of dry goods! He also ambushed a cute facial expression bag, hoping his friends could read it.

I sincerely wish everyone can find the right job.

1. What are the original types? Is null an object? What is the difference between original data type and complex data type storage?

  • There are 6 original types, namely undefined, null, bool, string, number, symbol (ES6 added).
  • Although the value returned by typeof null is object, null is not an object but one of the basic data types.
  • The original data type is stored in the stack memory and the value is stored.
  • Complex data types are stored in heap memory, and addresses are stored. When we assign an object to another variable, we copy the address, pointing to the same memory space. When one of the objects changes, the other object also changes.

2. does typeof correctly judge the type? What about instanceof? What is the implementation principle of instanceof?

First, typeof can correctly judge the basic data type, but except null, typeof null outputs objects.

However, for objects, typeof cannot correctly judge their type. a function of typeof can output’ function’, but in addition, all outputs are object. in this case, we cannot know the type of object accurately.

Instanceof can accurately judge complex data types, but cannot correctly judge basic data types. (Please stamp to correctly judge the data type:https://github.com/YvetteLau/ …

Instanceof is judged by the prototype chain. A instanceof B searches through A’s prototype chain layer by layer to see if there is a prototype equal to B.prototype If the top of A’s prototype chain is always found (null; That is,Object.prototype.__proto__), still not equal to B.prototype, then return false, otherwise return true.

Implementation code for instanceof:

// L instanceof R
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
    var O = R.prototype;// 取 R 的显式原型
    L = L.__proto__;    // 取 L 的隐式原型
    while (true) { 
        if (L === null) //已经找到顶层
            return false;  
        if (O === L)   //当 O 严格等于 L 时,返回 true
            return true; 
        L = L.__proto__;  //继续向上一层原型链查找
    } 
}

3. the difference between forof, forin and forEach,map.

  • For…of loop: With the iterator interface, you can use the for…of loop to traverse its members (attribute values). For…of loops can use arrays, Set and Map structures, some array-like objects, Generator objects, and strings. For…of loops call the traverser interface, which returns only attributes with numeric indexes. For ordinary objects, the for…of structure cannot be used directly, and an error will be reported. it cannot be used until the Iterator interface is deployed. The loop can be interrupted.
  • For…in loop: traverses the object’s own and inherited enumerable attributes, and cannot directly obtain attribute values. The loop can be interrupted.
  • ForEach: only the array can be traversed without interruption, and there is no return value (or the return value is considered undefined).
  • Map: only the array can be traversed without interruption, and the return value is the modified array.

PS: Object.keys (): returns an array of strings for all enumerable attributes of a given object.

Regarding whether forEach will change the original array, some small partners raised objections, so I wrote a code to test it (note that the array items are of complex data types).
Besides forEach, apis such as 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; //直接操作数组
});
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 } ]

If you do not know the iterator interface or for…of yet, please read the ES6 document first:Iterator and for…of loop

Please stamp for more details:https://github.com/YvetteLau/ …


4. How to judge whether a variable is an array?

  • Using Array.isArray judgment, if returns true, it is an array.
  • Use instanceof Array to judge, if it returns true, it is an array.
  • Use Object.prototype.toString.call to judge, if the value is [object Array], the description is an array.
  • Judging by the constructor, if it is an array, thenarr.constructor === Array(Not accurate, because we can specifyobj.constructor = Array)
function fn() {
    console.log(Array.isArray(arguments));   //false; 因为arguments是类数组,但不是数组
    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);

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

Class array:

1) Possess the length attribute and other attributes (indexes) are non-negative integers (indexes in the object will be treated as strings);

2) does not have methods that arrays have;

The class Array is an ordinary object, while the real array is of type Array.

Common class arrays include: functions’ arugments, DOM object lists (such as those obtained through document.querySelectorAll), jQuery objects (such as $(“div “)).

Class arrays can be converted to arrays:

//第一种方法
Array.prototype.slice.call(arrayLike, start);
//第二种方法
[...arrayLike];
//第三种方法:
Array.from(arrayLike);

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

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


What is the difference between = = and = = = 6.

= = = 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, judge whether the two types are the same, if so, judge whether the values are equal.
  2. If the types are different, perform type conversion
  3. Judge whether the comparison is null or undefined, and if so, return true.
  4. Judging whether the two types are string and number, and if so, converting the string into number
  5. Judging whether one of the parties is boolean, if so, converting boolean to number and judging again
  6. Judge whether one party is object and the other party is string, number or symbol. If so, convert object to the original type and judge again.
let person1 = {
    age: 25
}
let person2 = person1;
person2.gae = 20;
console.log(person1 === person2); //true,注意复杂数据类型,比较的是引用地址

Thinking:[] == ! []

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

  1. First of all, we need to know! Priority is higher than = = (More operator priorities can be seen:Operator precedence)
  2. ! []Conversion of reference types to boolean values is true, so! []Is false
  3. According to the fifth item in the above comparison step, one of which is boolean, convert boolean to number and judge, false to number, and the corresponding value is 0.
  4. According to article 6 of the above comparison step, if one side is Number, then convert object into number, and empty array into number, and the corresponding value is 0. (empty array into number, and the corresponding value is 0. if there is only one number in the array, then the number converted into number is the number, otherwise, it is NaN)
  5. 0 == 0; True

What is the difference between the class in es6 and the class in ES5?

  1. All methods defined within ES6 class are unenumerable;
  2. ES6 class must be called with new;
  3. There is no variable promotion in ES6 class;
  4. ES6 class is the strict mode by default;
  5. ES6 class subclass must call super () in the constructor of the parent class in order to have this object; In ES5, the relation of class inheritance is opposite. First there is this of subclass, and then the method of parent class is applied to this.

8. Which API of the array will change the original array?

API for modifying the original array are:

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: If each item of the array is a simple data type and the array is not directly manipulated.


What is the difference between let, const and var?

  • Variables defined by let and const will not be promoted, while variables defined by var will be promoted.
  • Let and const are block-level scopes in JS
  • Let and const do not allow duplicate declarations (errors will be thrown)
  • The variables defined by let and const will throw an error (forming a temporary dead zone) if used before the statement is defined, while var will not.
  • Const declares a read-only constant. Once declared, the value of a constant cannot be changed (if the declaration is an object, the reference address of the object cannot be changed)

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

Variable promotion means that variables can be used before declaration, with a value of undefined.

Within the code block, the variable is not available (an error will be thrown) until it is declared with the let/const command. This is grammatically called “temporary dead zone”. Temporary dead zones also mean typeof is no longer a 100% safe operation.

typeof x; // ReferenceError(暂时性死区,抛错)
let x;
typeof y; // 值是undefined,不会报错

The essence of temporary dead zone is that the variable to be used already exists as soon as it enters the current scope, but cannot be obtained. The variable can be obtained and used only when the line of code declaring the variable appears.


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), if so, this binds the newly created object.
  2. Whether the function is called through call,apply, or bind (i.e. hard binding), if so, this binds to the specified object.
  3. Whether the function is called in a context object (implicit binding), if so, this binds to that context object. Obj.foo ()
  4. If none of the above is true, the default binding is used. If it is in strict mode, it is bound to undefined, otherwise it is bound to a global object.
  5. If null or undefined is passed into call, apply or bind as the binding object of this, these values will be ignored when calling, and the default binding rule is actually applied.
  6. The arrow function does not have its own this, which inherits this from the previous code block.

Test whether this knowledge point has been successfully got (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);

If you don’t know much about this, please stamp:Hey, do you really understand this?


12. The difference between lexical scope and this.

  • Lexical scope is determined by where you write variables and block scopes when writing code.
  • This is bound at the time of call. What this points to depends entirely on the call location of the function (this article has already explained the problem of this point)

13. Talk about your understanding of JS execution context stack and scope chain.

The execution context is the environment in which the current JavaScript code is parsed and executed. JS execution context stack can be considered as a stack structure that stores function calls and follows the principle of first in and second out.

  • JavaScript is executed on a single thread, and all code is queued for execution.
  • At first, when the browser executes the global code, it first creates the global execution context and pushes it to the top of the execution stack.
  • Every time a function is executed, the execution context of the function is created and pushed to the top of the execution stack. Current Function Execution-After completion, the execution context of the current function is pushed out of 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 of the stack when the browser is closed.

Scope chain: Both LHS and RHS queries will start searching in the current scope. If they are not found, they will continue searching for the target identifier in the upper scope one scope at a time until reaching the global scope.


Is the problem difficult? Not difficult! Continue to challenge the difficult! Knowing the difficulty, we must continue!

14. What is closure? What is the function of closures? What are the usage scenarios for closures?

Closures are functions that have access to variables in the scope of another function. The most common way to create closures is to create another function within a function.

Closures have the following functions:

  1. Encapsulate private variables
  2. Imitate block-level scope (there is no block-level scope in ES5)
  3. Modules to Implement JS

What is 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 the method of parameter transmission is different:

  • Fn.call(obj, arg1, arg2, …) calls a function with a specified value of this and separately provided parameters (list of parameters).
  • Fn.apply(obj, [argsArray]), calls a function with a specified value of this and parameters provided as an array (or class array object).

Call core:

  • Set the function to the property of the passed-in parameter
  • Specifies this to the function and passes in the given argument to execute the function
  • If no parameter is passed in or the parameter is null, the default point is window/global
  • Delete function on parameter
Function.prototype.call = function (context) {
    /** 如果第一个参数传入的是 null 或者是 undefined, 那么指向this指向 window/global */
    /** 如果第一个参数传入的不是null或者是undefined, 那么必须是一个对象 */
    if (!context) {
        //context为null或者是undefined
        context = typeof window === 'undefined' ? global : window;
    }
    context.fn = this; //this指向的是当前的函数(Function的实例)
    let args = [...arguments].slice(1);//获取除了this指向对象以外的参数, 空数组slice后返回的仍然是空数组
    let result = context.fn(...args); //隐式绑定,当前函数的this指向了context.
    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.call(foo, 'programmer', 20);
// Selina programmer 20
bar.call(null, 'teacher', 25);
// 浏览器环境: Chirs teacher 25; node 环境: undefined teacher 25

apply:

The implementation of apply is very similar to call, but it should be noted that their parameters are different. the second parameter of apply is array or class array.

Function.prototype.apply = function (context, rest) {
    if (!context) {
        //context为null或者是undefined时,设置默认值
        context = typeof window === 'undefined' ? global : window;
    }
    context.fn = this;
    let result;
    if(rest === undefined || rest === null) {
        //undefined 或者 是 null 不是 Iterator 对象,不能被 ...
        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]);
// 浏览器环境: Chirs programmer 20; node 环境: undefined teacher 25

bind

There is an important difference between bind and call/apply. when a function is called/apply, it will be called directly, but bind will create a new function. When this new function is called, the first parameter of bind () will be used as this when it runs, and the following sequence of parameters will be passed in as its parameters before the passed arguments.

Function.prototype.my_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]; //bind传递的参数和函数调用时传递的参数拼接
        context = this instanceof Fn ? this : context || this;
        return self.apply(context, res);
    }
    //原型链
    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.my_bind(Yve, 22, 'enginner')('female');    

What is the principle of new? What is the difference between creating an object by new and by literal?

new:

  1. Create a new object.
  2. This new object will be linked by [[prototype]].
  3. Assigns the scope of the constructor to the new object, that is, this points to the new object.
  4. If the function does not return another object, the function call in the new expression will automatically return the new object.
function new(func) {
    lat target = {};
    target.__proto__ = func.prototype;
    let res = func.call(target);
    if (typeof(res) == "object" || typeof(res) == "function") {
        return res;
    }
    return target;
}

Literally create objects, do not call the Object constructor, concise and better performance;

The new Object () method to create an object is essentially a method call, which involves traversing the method in the proto chain. when the method is found, the stack information necessary for the method call will be produced. after the method call is finished, the stack will be released. the performance is not as good as the literal method.

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


17. Talk about your understanding of prototype?

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


18. What is a prototype chain? [What is the problem solved by the prototype chain? 】

The prototype chain mainly solves the inheritance problem.

Each object has a prototype object that passes through theproto(Pronunciation: dunder proto) Pointer points to its prototype object and inherits methods and attributes from it. At the same time, prototype object may also have prototypes, which point to null (Object.proptotype.__proto__Pointing to null). This relationship is called prototype chain, through which an object can have attributes and methods defined in other objects.

The relationship between the constructors Parent, Parent.prototype and instance p is as follows:(p.__proto__ === Parent.prototype)


19. prototype and__proto__What is the difference?

Prototype is an attribute of the constructor.

__proto__Is an attribute that exists for each instance and can access the [[prototype]] attribute.

Of instance__proto__The prototype of its constructor points 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

20. Use ES5 to implement an inheritance?

Combination inheritance (the most common inheritance method)

function SuperType() {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function() {
    console.log(this.name);
}

function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;

SubType.prototype.sayAge = function() {
    console.log(this.age);
}

For the implementation of other inheritance methods, please refer to JavaScript Advanced Programming


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

Shallow copy refers to copying only the first-level objects. However, when the attribute of an object is a reference type, what is copied is its reference. When the value pointed to by the reference changes, it will also change accordingly.

Deep copy copies variable values. For variables of non-basic type, it will be copied after recursion to variables of basic type. The object after the deep copy is completely isolated from the original object and does not affect each other, and the modification of one object does not affect the other.

Implement a deep copy:

function deepClone(obj) { //递归拷贝
    if(obj === null) return null; //null 的情况
    if(obj instanceof RegExp) return new RegExp(obj);
    if(obj instanceof Date) return new Date(obj);
    if(typeof obj !== 'object') {
        //如果不是复杂数据类型,直接返回
        return obj;
    }
    /**
     * 如果obj是数组,那么 obj.constructor 是 [Function: Array]
     * 如果obj是对象,那么 obj.constructor 是 [Function: Object]
     */
    let t = new obj.constructor();
    for(let key in obj) {
        //如果 obj[key] 是复杂数据类型,递归
        t[key] = deepClone(obj[key]);
    }
    return t;
}

Can’t you watch it anymore? Other people’s questions will become your questions

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

The functions of anti-shake and throttling are to prevent functions from being called many times. The difference is that if a user triggers this function all the time and the interval between triggering functions is less than the set time, the function will be called only once in case of anti-shake and once every certain time in case of throttling.

De Bounce: The function will only be executed once in n seconds. If the high-frequency event is triggered again in n seconds, the time will be recalculated.

function debounce(func, wait, immediate=true) {
    let timeout, context, args;
        // 延迟执行函数
        const later = () => setTimeout(() => {
            // 延迟函数执行完毕,清空定时器
            timeout = null
            // 延迟执行的情况下,函数会在延迟函数中执行
            // 使用到之前缓存的参数和上下文
            if (!immediate) {
                func.apply(context, args);
                context = args = null;
            }
        }, wait);
        let debounced = function (...params) {
            if (!timeout) {
                timeout = later();
                if (immediate) {
                    //立即执行
                    func.apply(this, params);
                } else {
                    //闭包
                    context = this;
                    args = params;
                }
            } else {
                clearTimeout(timeout);
                timeout = later();
            }
        }
    debounced.cancel = function () {
        clearTimeout(timeout);
        timeout = null;
    };
    return debounced;
};

Anti-shake application scenario:

  • Each resize/scroll triggers a statistical event
  • Verification of text input (send AJAX request for verification after continuous text input, and verify once)

Throttle: High-frequency events will only be executed once within the specified time, and the second time will only be executed after being executed once and larger than the set execution cycle.

//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) {
            // 判断是否设置了定时器和 trailing
            timeout = setTimeout(later, remaining);
        }
        return result;
    };

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

    return throttled;
};

The application scenarios of function throttling are:

  • Implementation of drag-and-drop function of DOM element (mousemove)
  • Mousedown/keydown Event in Shooting Game (only one bullet can be fired per unit time)
  • Calculate the mouse movement distance (mousemove)
  • Canvas analog sketchpad function (mousemove)
  • Search association (keyup)
  • Monitor scrolling events to determine whether more is automatically loaded at the bottom of the page: after debounce is added to scroll, only after the user stops scrolling will it be determined whether it has reached the bottom of the page; If it is throttle, the page will be judged at intervals as long as it scrolls.

23. Take 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
});

24. What are the new features of ES6?

  1. New block-level scope (let,const)
  2. Provides a syntax sugar (class) that defines a class
  3. A new basic data type (Symbol) has been added.
  4. Deconstruction and assignment of variables have been added
  5. Function parameters allow setting default values, rest parameters are introduced, and arrow functions are added
  6. Some apis have been added to the array, such as isArray/from/of method; Entries (), keys (), values () and other methods have been added to the array instance
  7. Objects and arrays have added extension operators
  8. ES6 has added modularization (import/export)
  9. ES6 has added Set and Map data structures
  10. ES6 natively provides Proxy constructors to generate Proxy instances
  11. ES6 adds a Generator and an Iterator

25. Why is there an error in SetTimeout countdown?

SetTimeout () just inserts the event into the “task queue”. The main thread will not execute the callback function it specifies until the current code (execution stack) has finished executing. If the current code takes a long time, it may take a long time, so there is no guarantee that the callback function will be executed at the time specified by setTimeout (). Therefore, the second parameter of setTimeout () represents the minimum time, not the exact time.

The HTML5 standard stipulates that the minimum value of the second parameter of setTimeout () must not be less than 4 milliseconds. if it is lower than this value, the default value is 4 milliseconds. Before that. Older browsers set the minimum time at 10 milliseconds. In addition, for those DOM changes (especially those involving page re-rendering), it is usually executed at intervals of 16 milliseconds. At this time, the effect of using requestAnimationFrame () is better than setTimeout ();


26. Why 0.1+0.2! = 0.3 ?

0.1 + 0.2 ! = 0.3 due to loss of precision in the process of binary conversion and advanced operations.

The following is a detailed explanation:

JavaScript uses the Number type to represent numbers (integer and floating point numbers) and 64 bits to represent a number.

Picture description:

  • Bit 0: sign bit, 0 for positive number and 1 for negative number (s)
  • Bit 1 to Bit 11: Storage Index Part (E)
  • Bit 12 to Bit 63: Stores fractional part (i.e., significant number) f

The computer can’t directly operate on decimal numbers. It needs to convert to binary according to IEEE 754 standard and then operate on order.

1. Decimal conversion

Conversion of 0.1 and 0.2 to binary will loop indefinitely.

0.1 -> 0.0001100110011001...(无限循环)
0.2 -> 0.0011001100110011...(无限循环)

However, due to the limitation of IEEE 754 mantissa bits, the following redundant bits need to be truncated, thus the precision has been lost in the conversion between decimal systems.

2. Pair order operation

Due to the difference in the number of exponent bits, precision loss may also occur in this part of the operation that needs to be performed on the order.

According to the above two operations (including the precision loss of two steps), the final result is

0.0100110011001100110011001100110011001100110011001100

After the result is converted into decimal, it is 0.30000000000000004.

27. promise has several states. What are its advantages and disadvantages?

Promise has three states: fulfilled, rejected, pending.

Advantages of Promise:

  1. Once the state changes, it will not change again, and this result can be obtained at any time.
  2. Asynchronous operations can be expressed in the flow of synchronous operations, thus avoiding callback functions nested layer by layer.

Disadvantages of Promise:

  1. Promise cannot be cancelled
  2. When in the pending state, it is impossible to know where the current progress is.

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

The constructor of Promise is executed synchronously. The method in then is executed asynchronously.

The then implementation of promise is detailed in:Promise source code implementation


29. What is the difference between Promise and setTimeout?

Promise is a micro task and setTimeout is a macro task. Promise always precedes setTimeout in the same event cycle.


30. how to realize Promise.all?

To realize Promise.all, first we need to know the function of Promise.all:

  1. If the passed-in parameter is an empty iteratable object, then the promise object callback is resolve, only in this case, it is executed synchronously, and the others are returned asynchronously.
  2. If the passed parameter does not contain any promise, an asynchronous completion is returned.

The callback completes when all the promises in promises are “complete” or when the parameter does not contain Promise.

  1. If a promise fails in the parameter, the promise object returned by Promise.all fails
  2. In any case, the result of promise’s completion status returned by Promise.all is an array
Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        let index = 0;
        let result = [];
        if (promises.length === 0) {
            resolve(result);
        } else {
            setTimeout(() => {
                function processValue(i, data) {
                    result[i] = data;
                    if (++index === promises.length) {
                        resolve(result);
                    }
                }
                for (let i = 0; i < promises.length; i++) {
                    //promises[i] 可能是普通值
                    Promise.resolve(promises[i]).then((data) => {
                        processValue(i, data);
                    }, (err) => {
                        reject(err);
                        return;
                    });
                }
            })
        }
    });
}

If you want to know more about the source code implementation of Promise, please refer to another article of mine:Source code implementation of Promise (perfectly conforms to Promise/A+ specification)


31. how to realize Promise.finally?

No matter whether you succeed or fail, you will go to finally, and after finally, you can continue then. And will pass the value intact to the following 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;
        });
    });
}

32. What is the function Coritization? Implementation of sum(1)(2)(3) returns the sum of 1,2,3

Corellization of functions is a technique that transforms a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the original function), and returns a new function that accepts the remaining parameters and returns the result.

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

Extension: Realize a curry function and Curry the ordinary 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

If you encounter more native JS problems during the interview, or have some JS knowledge that is not covered in this article and has certain difficulty, please leave a message for me. Your question will appear in subsequent articles ~

The writing of this article took a lot of time. In the process, I also learned a lot of knowledge. Thank you for your friends’ willingness to spend precious time reading this article. If this article gives you some help or inspiration, please don’t be stingy with your praise and Star. Your affirmation is my greatest motivation.https://github.com/YvetteLau/ …

Follow-up writing program

1. The Native JS that You Must Know in Winter Job Hunting Season (Part 2)

2. “CSS You Must Know in Winter Job Hunting Season”

3. Front-end Safety You Must Know in Winter Job Hunting Season

4. Some Browser Knowledge You Must Know in Winter Job Hunting Season

5. Performance Optimization You Must Know in Winter Job Hunting Season

For React technology stack:

1. React series you must understand during the winter job-hunting season

2. The ReactNative series that you must understand during the cold winter job season

Reference articles:

  1. https://www.ibm.com/developer …
  2. https://juejin.im/post/5c7736 …
  3. Some of the interview questions were selected.
  4. Some of the interview questions mentioned in the article were selected:https://juejin.im/post/5bc92e …
  5. Special note:0.1 + 0.2 ! == 0.3The answer to this question makes extensive use of the text of this article:https://juejin.im/post/5b90e0 …
  6. I chose some interview questions that my friends met when they interviewed large factories.
  7. JavaSctipt, You Don’t Know
  8. JavaScript Advanced Programming
  9. https://github.com/hanzichi/u …

Recommend to pay attention to my public number:

clipboard.png