Preface 🧐

As we all know, JS in the front-end interview proportion can be said to be very large. Basically in every interview, more than 40% of the questions are JS questions. Js not only inspects the basic ability of a front end person, more importantly, the front end can be said to be based on JS, so it also inspects our code ability and logical thinking. If js fails in the interview front end, it is actually quite dangerous.

In the following article, I will explain all the topics in the whole autumn recruitment preparation process. Among them, some knowledge points are a very wide range, but if put in the interview series, it can only be a general introduction. I will link the articles I wrote before and articles of other related modules to mark after the title, so that you can have a more detailed understanding of the expanded knowledge points of the current module.

Here we begin the explanation of this article ~πŸ“š

πŸ₯³ Mind mapping

Before you really start, use a mind map to understand the text. See πŸ‘‡ below for details

Now that mind mapping is in the bag, it’s time to start building up the js knowledge system

😏 1. JS specification

1. A few basic JavaScript specifications.

  • for-inVariables in loops should be explicitly scoped using the let keyword to avoid scope contamination.
for(let i in obj){
    
}
Copy the code
  • Used when comparing Boolean values/values= = = / ! = =To compare;
  • switchStatement must containdefaultBranch;
  • Do not use global functions;
  • Use object literals insteadnew ArrayIn this form, an example of object literals is given below.
let person = {
	name:'Joe'.age:13.like: ['Play basketball'.'Play volleyball']}Copy the code

2. Knowledge of native JavaScript.

Data types, operations, Objects, Functions, inheritance, closures, scope, prototype chains, events, RegExp, JSON, Ajax, DOM, BOM, Memory leaks, Asynchronous loading, template engine, front-end MVC, Routing, Modularity, Canvas, ECMAScript.

3, talk about the understanding of JS.

Is a prototype based dynamic language, the main features are this, prototype and prototype chain.

JS is strictly divided into: language standard part (ECMAScript) + host environment part.

Language Standards

  • In 2015,releaseES6, introducing features that make it possible to write large projects, standard sinceIn 2015,After the year number as a code, a year.

Part of host environment

  • Included in the browser hosting environmentDOM + BOM η­‰
  • inNodeThe host environment includes files, databases, networks, interactions with the operating system, and so on

4. JS native drag node

  • Bind nodes that need to be draggedmousedown ,mousemove ,mouseupEvents.
  • mousedownAfter the event is triggered, drag begins.
  • mousemoveIs required to passevent.clientX ε’Œ clientYGet the drag position and in real timeUpdate location.
  • mouseupWhen, the drag ends.
  • Note the browser boundary values and set the drag range.

5. Talk about your understanding of ES6

  • New template string (isJavaScriptProvides a simple string interpolation function.
  • Arrow function.
  • for-of(Used to iterate over data — for example, values in an array).
  • argumentsObjects can be perfectly replaced by undefined arguments and default arguments.
  • ES6 ε°† promiseObject incorporated into the specification, provided nativepromiseObject.
  • increasedlet ε’Œ constCommand to declare variables.
  • And then there is the introductionmoduleThe concept of modules.

6, Do you know ES6 class?

Class in ES6 adds methods directly to the function object of the class, rather than to the prototype object of the function object.

7. Share your understanding of AMD and Commonjs

  • CommonJSIs a specification for server-side modules,Node.jsThis specification was adopted.
  • CommonJSThe canonical load module is synchronous, which means that subsequent operations cannot be performed until the load is complete.AMDThe specification loads modules asynchronously and allows you to specify callback functions.
  • AMDThe recommended style is to return an object as a module object.CommonJSThe style is through tomodule.exports ζˆ– exportsTo expose the module object.

8. How to understand front-end modularity

Front-end modularization is a complex file programming one independent module, such as JS files and so on, divided into independent modules is conducive to reuse (reuse) and maintenance (version iteration), which will lead to the problem of interdependence between modules, so there are commonJS specifications, AMD, CMD specifications and so on, And webpack, a tool for JS packaging (mutations, etc.).

9. Object-oriented programming

  • The basic idea is to use object, class, inheritance, encapsulation and other basic concepts to carry on the program design;
  • Easy maintenance;
  • Easy extension;
  • The reuse and inheritance of development work are high, and the repetitive workload is reduced;
  • Shorten the development cycle.

10. Ever used TypeScript? What does it do?

TypeScript adds type support to JS and provides support for the latest version of ES syntax, making it easier for teams to collaborate and troubleshoot large projects.

11. Has PWA ever been used? How does serviceWorker work?

Progressive Web Apps (PWA) is a concept Google introduced in late 2015. It’s basically a Web application, but looks and feels like a native app. Pwa-enabled websites can provide offline work, push notifications, and device hardware access.

A Service Worker is a script that the browser runs in the background independently of the web page, opening the door to functionality that does not require web pages or user interaction. They now include features like push notifications and background synchronization. In the future, Service workers will support other features such as periodic synchronization or geo-fencing.

Note: Progressive Network Application

😲 2. Data type

1, Q: 0.1+0.2 === 0.3? Why is that?

In normal mathematical logic, 0.1+0.2=0.3 is correct, but in JavaScript 0.1+0.2! == 0.3, why is that? This question is also occasionally used as an interview question to test candidates’ understanding of JavaScript numbers.

0.1 + 0.2= =0.3 // false
Copy the code

In JS, the binary floating point numbers 0.1 and 0.2 are not exact, so they do not add up to exactly 0.3, but a close number 0.30000000000000004, so the conditional judgment result is false.

The reason is that JS adopts the DOUBLE precision standard of IEEE 754, so when storing data encoding inside the computer, 0.1 is not an exact 0.1, but a 0.1 with rounding error. By the time the code is compiled or parsed, 0.1 has been rounded to an internal computer number so close that a small rounding error has occurred before the calculation has even begun. This is why 0.1 + 0.2 does not equal 0.3.

So how do you avoid this problem?

The most common method is to convert a floating point number to an integer, because integers are exactly representable.

Usually you take the number and you raise it by 10 to the NTH power and you divide it by 10 to the NTH power, usually 1,000.

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

What are the JS data types? Where does it exist? What is the way of judging?

(1) JS data type

Js data types include basic data types and reference data types.

(2) Where is it stored?

Basic data types:

The basic data type is Numer, Boolean, String, null, undefined, Symbol (ES6 new), BigInt (ES2020) equivalent, which are stored in memory stack. That is, directly accessing the variable can get the value of the corresponding variable stored on the stack.

If you assign the value of one variable to another variable, the two variables are independent in memory. Changing the value of either variable does not affect the other variable. That’s the basic data type.

Reference data types:

Reference data types, Object, Array, Function, etc., are stored in the stack and heap in memory. To access the value of a reference type, we need to access the variable’s address in the stack (pointing to the value in the heap), and then access the data stored in the heap through this address. This is the reference data type.

(3) Common judgment methods: typeof, Instanceof, ===

1) typeof:

Definition: Returns a string representation of a data type (lowercase)

Usage: Typeof + variables

It can be judged that:

  • Undefined/value/string/Boolean/function (Return ‘undefined’/’number’/’string’/’ Boolean ‘/ ‘function’)

  • Null and object, object and array (null, array, object all return ‘object’)

<script type="text/javascript">
    console.log(typeof "Tony");                / / return a string
    console.log(typeof 5.01);                  / / return number
    console.log(typeof false);                 / / returns a Boolean
    console.log(typeof undefined);             / / returns undefined
    console.log(typeof null);                  / / return the object
    console.log(typeof [1.2.3.4]);             / / return the object
    console.log(typeof {name:'John'.age:34}); / / return the object
</script>
Copy the code

2) instanceof:

Definition: Determines the specific type of an object

Usage: b instanceof A β†’ indicates whether b is an instanceof A

It can be judged that:

It is used to determine the types of Object data: Object, Array and Function

String, Number, and Boolean values are set to false and created by calling the constructor to true

<script type="text/javascript">
    let str = new String("hello world")     //console.log(str instanceof String); And true
    str = "hello world"                     //console.log(str instanceof String); - > false

    let num = new Number(44)                //console.log(num instanceof Number); And true
    num = 44                                //console.log(num instanceof Number); - > false

    let bool = new Boolean(true)            //console.log(bool instanceof Boolean); And true
    bool = true                             //console.log(bool instanceof Boolean); - > false

</script>
Copy the code
<script type="text/javascript">
    var items = []; 
    var object = {}; 
    
    function reflect(value) { 
        return value;
    } 
 
    console.log(items instanceof Array);        // true 
    console.log(items instanceof Object);       // true 
    console.log(object instanceof Object);      // true 
    console.log(object instanceof Array);       // false 
    console.log(reflect instanceof Function);   // true 
    console.log(reflect instanceof Object);     // true 
Copy the code

3) = = = :

Undefined, null

<script type="text/javascript">
    let str;
    console.log(typeof str, str === undefined);   //'undefined', true

    let str2 = null;
    console.log(typeof str2, str2 === null); // 'object', true

</script>
Copy the code

What is shallow copy? What is deep copy? Explain and code separately.

(1) Shallow copy

The so-called shallow copy refers to the assignment of a variable to another variable. If the value of one variable changes, the values of the two variables change. That is, for the shallow copy, some data in the newly copied object will still change with the changes of the source object.

/ / analysis
function shallowCopy(obj){
    let copyObj = {};
    for(let i in obj){
        copyObj[i] = obj[i];
    }
    return copyObj;
}

/ / instance
let a = {
    name: 'Joe'.age: 19.like: ['Play basketball'.'singing'.'dancing']}let b = shallowCopy(a);

a.name = 'bill';
a.like[0] = 'Play table tennis';
console.log(a);
console.log(b);
Copy the code

(2) Deep copy

Definition: Deep copy means that all the data in the newly copied object is independent and does not change with the change of the source object.

There are two types of deep copy: recursive copy and deep copy using JSON functions.

  • The implementation principle of recursive copy is: to obtain each element in the variable, if the basic type value is encountered, directly obtain; If a reference type value is encountered, the fetch continues for each element inside the value.
  • JSON deep copy is implemented by converting the value of a variable to a string and then converting it to an object and assigning it to a new variable.

Limitations: The limitations of deep copy are that undefined is ignored, functions cannot be serialized, and objects cannot be looping referenced.

Recursive copy code:

/ / analysis
function deepCopy(obj){
    // Check whether it is a reference data type
    if(typeof obj === 'object') {let result = obj.constructor === Array ? [] : {};
		// Continue traversing the reference type if the traversal is not complete
        for(let i in obj){
            result[i] =  typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i];
        }

        return result;
    }
    // It is a basic data type and returns directly from assignment
    else{
        returnobj; }}// Example - deep copy using recursive functions
let c = {
    name:'Joe'.age:12.like: ['Play table tennis'.'Play badminton'.'Do Tai Chi']}let d = deepCopy(c);

c.name = 'bill';
c.like[0] = 'Play basketball';
console.log(c);
console.log(d);
Copy the code

JSON deep copy code:

// example - deep copy using JSON functions
let e = {
    name: 'Joe'.age: 19.like: ['Play badminton'.'singing'.'dancing']}let f = JSON.parse(JSON.stringify(e));

// Note: deep copy of JSON functions cannot copy re, Date, method functions, etc

e.name = 'bill';
e.like[0] = 'Play table tennis';

// console.log(e);
// console.log(f);
Copy the code

Here you can refer to an article I wrote before to help understand the application of πŸ‘‰ stack in the front end, and also learn about deep copy and shallow copy!

4, how to express the JS integer?

The JS integer is represented by the Number type, which complies with IEEE 754 standard and represents a Number by 64 bits, namely 1+11+52 (sign bit + exponential bit + significant decimal bit). The maximum safe digit is 253-1, corresponding to a 16-bit decimal Number.

Note: one decimal digit corresponds to four binary digits

5. What is the storage space for Number? What if the background sends a number that exceeds the maximum?

Math.pow(2,53),53 is a significant number; If the background sends a number that exceeds the maximum, truncation occurs, equal to the maximum security number 253-1 that JS can support.

6. What is NAN and what will typeof output be?

Not a Number: indicates a non-number.

typeof NaN= = ='number'; //true
Copy the code

What is the use of Symbol?

  • Can be used to represent a unique variable, preventing naming conflicts.
  • In addition to that,SymbolIt can also be usedSimulation of privateProperties.
  • Detailed articles are added at πŸ‘‡
  • Interviewer: What is the use of the JavaScript primitive data type Symbol?
  • Link: www.cnblogs.com/lzkwin/p/12…

8, null, undefined difference

  • undefinedIndicates the value does not exist.
  • undefinedIs a primitive value that means “none” or “missing value”, that is, there should be a value here, butIt’s not defined. It returns when it tries to readundefined 。
  • For example, when a variable is declared but not assigned, equalsundefined 。
  • nullIndicates that an object has been defined with a null value.
  • nullIs an object (empty object, noneAny properties and methods).
  • For example, the parameter of a function is not an object.
  • In the validationnullBe sure to use= = =Because the= =Unable to distinguish betweennull ε’Œ undefined 。

JS implicit conversion, display conversion

ValueOf is called when a non-base type is converted, and toString is called if valueOf cannot return a valueOf the base type.

(1) String and number

  • The “+” operator, if any of them are strings, converts them to strings and performs string concatenation.
  • The “-” operator, which converts to a number, and the subtraction (-a, a*1, a/1) can all be implicitly cast.
[] + {} and {} + []Copy the code

(2) Boolean value to number

  • 1 + true = 2;
  • 1 + false = 1;

(3) Convert to a Boolean value

  • The second in for
  • while
  • if
  • Ternary expression
  • | | (logical or) and && (logical) and the number of operations on the left

(4) symbols

  • Cannot be converted to a number
  • Can be converted to a Boolean value (both true)
  • Can be converted to the string “Symbol(cool)”

(5) Loose equality and strict equality

Loose equality allows casting, while strict equality does not.

(1) Strings and numbers

  • Convert to numbers and compare

β‘‘ Other types and Boolean types

  • First, the Boolean type is converted to a number, and then the comparison continues

β‘’ Object and non-object

  • Execute object’sToPrimitive(object) and continue the comparison

β‘£ List of false values

  • undefined
  • null
  • false
  • Plus 0, minus 0, NaN
  • “”

10. Introduce the built-in objects in JS

  • Object 是 JavascriptThe parent object of all objects in;
  • Other data encapsulation class objects:Object 、Array 、Boolean 、Number ε’Œ String;
  • Other objects:Function 、Arguments 、Math 、Date 、RegExp 、Error.

What methods do js have to define objects

  • Object literals:let obj = {} οΌ›
  • Constructor:let obj = new Object() οΌ›
  • Object. The create () :let obj = Object.create(object.prototype) οΌ›

12. How to tell if an object is empty?

Object.keys(obj).length === 0
Copy the code

Get getUrlParams(url)

// Encapsulate the getUrlParams function to parse the parameters of the URL into objects
function getUrlParams(url){
    let obj = {};

    if(url.indexOf('? ') = = = -1) {return obj;
    }

    let first_res = url.split('? ') [1];
    let second_res = first_res.split('&');
    
    for(let i in second_res){
        third = second_res[i].split('=');
        obj[third[0]] = third[1];
    }
    return obj;
}


// Test the code

let URL = 'https://www.sogou.com/web?ie=UTF-8&query= search content & _em = 3';
console.log(getUrlParams(URL));

Copy the code

14. What functions can arrays call?

  • pushAdds elements to the end of the array
  • popRemoves and returns the last element of the array
  • spliceAdd/remove elements
  • sliceReturns the selected element
  • shiftDelete the first element and return
  • unshiftAdds one or more elements to the beginning of the array and returns the new length
  • sortSort array elements
  • findReturns the first element of the array that passes the test
  • findIndex
  • map/filter/reduceAnd other functional programming methods
  • Methods on the prototype chain:toString/valueOf

Arguments is an array. Class array to array method understand?

It’s a class array, it’s a duck type category, but it looks like an array.

  • . The operator
  • Array.from
  • Array.prototype.slice.apply(arguments)

16, how to determine the type of array?

// Instanceof method 1
let arr = [1.2.3];
console.log(arr instanceof Array);

// Constructor method
let arr = [1.2.3];
console.log(arr.constructor === Array);

// Method 3: isArray
let arr = [1.2.3];
console.log(Array.isArray(arr));

// Object. Prototype
let arr = [1.2.3];
console.log(Object.prototype.toString.call(arr) === '[object Array]');

// Array.__proto__ method
let arr = [1.2.3];
console.log(arr.__proto__ === Array.prototype);

// Method 6: Object.getProtoTypeof method
let arr = [1.2.3];
console.log(Object.getPrototypeOf(arr) === Array.prototype);

/ / method seven: Array. Prototype. IsPrototypeOf method
let arr = [1.2.3];
console.log(Array.prototype.isPrototypeOf(arr));
Copy the code

17, 写 作 钘 : Sort quickly scrambles arrays

let arr = [1.2.3.4.5.6.7.8.9.10];
arr.sort(() = > Math.random() - 0.5);
// sort is used to swap positions if the result is greater than or equal to 0, and swap positions if the result is less than 0.
Copy the code

18, handwriting: array to redo operation

/* Array deduplicate: make all elements of the array unique, no duplicate elements */

// Create an array with repeating elements
let arr = [1.1.2.3.3.6.7.2.9.9]

// The first method uses the Set data structure + array.from () function
function removeRepeat1(arr) {
    return Array.from(new Set(arr))
}

// The second method is to use the Set data structure +... Extended operator
function removeRepeat2(arr) {
    return [...new Set(arr)]
}

// Third method: use indexOf
function removeRepeat3(arr) {
    let new_arr = []

    for(let i in arr) {

        let item = arr[i]

        if(new_arr.indexOf(item) === -1) {
            new_arr.push(item)
        }
    }

    return new_arr
}

// Fourth method: use the includes function
function removeRepeat4(arr) {
    let new_arr = []

    for(let i in arr) {

        let item = arr[i]

        if(! new_arr.includes(item)) { new_arr.push(item) } }return new_arr
}

// The fifth method uses the filter function
function removeRepeat5(arr) {
    return arr.filter((value, index) = > {
        return arr.indexOf(value) === index
    })
}

// The sixth method: use Map data structures
function removeRepeat6(arr) {

    let map = new Map(a)let new_arr = []

    for(let i in arr) {
        
        let item = arr[i]

        if(! map.has(item)) { map.set(item,true)
            new_arr.push(item)
        }
    }

    return new_arr
}

// Test method
console.log(removeRepeat1(arr));
console.log(removeRepeat2(arr));
console.log(removeRepeat3(arr));
console.log(removeRepeat4(arr));
console.log(removeRepeat5(arr));
console.log(removeRepeat6(arr));
Copy the code

19, handwriting: array flattening

/* Array flattening transforms a multidimensional array into a one-dimensional array */

// Multi-dimensional array
let arr = [1.2[3.4[6.7]]]

// The first method is flat()
function flatArr1(arr) {
    return arr.flat(Infinity)}// The second method is regular matching
function flatArr2(arr) {
    return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g.' ') + '] ')}// The third method uses reduce() to iterate over all elements
function flatArr3(arr) {
    return arr.reduce((i, j) = > {
        return i.concat(Array.isArray(j)? flatArr3(j) : j)
    }, [])
}

// The fourth method is to use the recursive function directly
function flatArr4(arr) {
    let new_arr = []                                                     

    function innerArr(v) {
        for(let i in v) {
            let item = v[i]

            if(Array.isArray(item)) {
                innerArr(item)
            } else {
                new_arr.push(item)
            }
        }
    }

    innerArr(arr)

    return new_arr
}

// Method test
console.log(flatArr1(arr));
console.log(flatArr2(arr));
console.log(flatArr3(arr));
console.log(flatArr4(arr));
Copy the code

20,newWhat exactly does the operator do?

The procedure for new an object is:

  • Create an empty object;
  • On the new object[prototype]Binding (i.e.son. __ proto __ =father.prototype);
  • New object and function callsthisIt’s bound;
  • Execute the methods in the constructor;
  • If the function returns no value, the new object is automatically returned.

21, handwriting: handwriting a new method

function father(name){
    this.name = name;
    this.sayname = function(){
        console.log(this.name); }}function myNew(ctx, ... args){ / /... Args is the ES6 expansion; arguments can also be used
    // Create an empty object with Oject
    let obj = new Object(a);// The new object performs a Prototype connection
    obj.__proto__ = ctx.prototype;
    // The new object is bound to the function call's this
    letres = ctx.call(obj, ... args);// Return obj if null or undefined, res if not
    return res instanceof Object ? res : obj;
}

let son = myNew(father, 'Bob');
son.sayname();
Copy the code

22, how to implement JS inheritance?

  • Prototype chain inheritance
  • Embezzle constructor inheritance
  • Combination of inheritance
  • Primary inheritance
  • Inherited inheritance
  • Parasitic combinatorial inheritance
  • The class inheritance
  • Detailed explanation of the article added πŸ‘‡
  • This article reviews seven common inheritance schemes in JavaScript
  • Link: blog.csdn.net/weixin_4480…
  • For js inheritance problem, to clarify the relationship between several inheritance, as well as their advantages and disadvantages, and handwriting each kind of inheritance.

JS garbage collection mechanism

Simply put, the garbage collection mechanism is to remove useless variables, free up more memory, and show better performance.

Necessity: Because strings, objects, and arrays do not have fixed sizes, they can only be allocated dynamically when their sizes are known.

Every time a JavaScript program creates a string, array, or object, the interpreter must allocate memory to store that entity. Whenever memory is allocated dynamically like this, it must eventually be freed so that it can be reused, otherwise the JavaScript interpreter will consume all available memory in the system, causing the system to crash.

JS, unlike C/C++, has its own GarbageCollection mechanism.

The JavaScript interpreter can detect when the program is no longer using an object, and when it determines that an object is useless, it knows that the object is no longer needed and can free up its memory.

Such as:

var a="hello world"; 
var b="world"; 
var a=b; 
// At this point, "Hello world" is freed, freeing memory for re-reference
Copy the code

Garbage collection methods: mark removal method, reference counting method.

Mark clearance

This is the most common garbage collection method. When a variable enters the environment, it is marked as “entering the environment”. Logically, the memory occupied by the variables entering the environment can never be freed, as long as the execution process enters the corresponding environment, they can be used. When leaving the environment, mark it as “leaving the environment.”

Garbage collector at run time will add tags to variables are stored in the memory is (all), and then remove the variables, the environment variables and the environment variables of the referenced variable (conditional remove tag), delete all the marked variables, delete the variable cannot be accessed in the environment variable so they will be deleted, Finally, the garbage collector finishes cleaning up the memory and reclaims the memory they occupy.

Reference counting method

Another, less common method is reference counting, which means the number of times each value is not referenced. When a variable is declared and a value of a reference type is assigned to the variable, the number of references to the value is 1; On the contrary, if contains a reference to the value of variables and made another value, the cited reference values of the original is minus 1, when the value of the reference number is 0, that there is no way to access the value again, so just show the recycling of the memory come in, so that the garbage collector runs again, These values with zero references are released.

Memory leaks occur with reference counting, and here’s why:

function problem() { 
    var objA = new Object(a);var objB = new Object(a); objA.someOtherObject = objB; objB.anotherObject = objA; }Copy the code

In this example, objA and objB refer to each other through their properties, so that both objects are referenced 2 times. In the reference-counting strategy, since both objects are out of scope after the function is executed, after the function is executed, because the count is not zero, Such cross-references in large numbers can cause memory leaks.

Especially in DOM objects, it’s easy to have this problem:

var element=document.getElementByIdοΌˆβ€™β€˜οΌ‰; 
var myObj=new Object(a); myObj.element=element; element.someObject=myObj;Copy the code

So there’s no recycling.

  • Detailed explanation of the article added πŸ‘‡

  • JavaScript’s garbage collection mechanism removes useless variables and frees up excess memory for better performance

  • Link: blog.csdn.net/l_ppp/artic…

🀐 scope, prototype chain, closure

1. Scope

(1) What is scope?

There are only two types of scope in ES5: global scope and function scope. In Javascript, we define a scope as a set of rules that govern how the engine looks up variables (variable names and function names) based on identifier names in the current scope and nested subscopes.

Scope, when accessing a variable, the compiler executes the code by first looking for the identifier in the current scope. If not, it looks in the parent scope. If not, it looks up until it reaches the global scope. This can be understood as the variables declared in this context and the scope of the declaration, which can be divided into block-level scope and function scope.

(2) What is scope chain?

  • A scope chain can be thought of as a chain connecting variable objects in sequence.
  • The scope is different in each execution environment.
  • When we reference a variable, we will follow the scope chain of the current execution environment, starting from the beginning of the scope chain, search for the corresponding variable, until we find the end of the scope chain, an error is reportedundefined 。
  • Scope chains guarantee ordered access to variables.
  • Pay attention to: Scope chains can onlyUp accessAnd to thewindowThe object is terminated.

2. Prototype chain

(1) What is a prototype? What is a prototype chain?

  • Prototype and prototype chainIn:JavascriptIn, each object initializes a property within it, which isprototype(Prototype). When we access a property of an object, if the property doesn’t exist inside the object, it goesprototypeLook for this property, this propertyprototypeYou’ll have your ownprototype, so have been looking for down, so step by step to find the shape of a chain, and through[[prototype]]Property join, the process of this join is calledPrototype chain.
  • Relationship between:instance.constructor.prototype === instance.__ proto __ οΌ›

(2) What is prototype chain inheritance?

When there are two constructors A and B, the prototype object of one constructor A is connected to the prototype object of another constructor B by its [[prototype]] attribute, this process is called prototype inheritance.

(3) Handwriting: The instance principle of prototype chain

// Check whether A is an instance of B
const instanceOf = (A, B) = >{
    // define A pointer P to A
    let p = A;
    // Continue execution if P exists
    while(p){
        // check whether the P value is equal to B's prototype object
        if(p === B.prototype){
            return true;
        }
        // Iterate through the prototype chain of A until you find the prototype of B
        p = p.__proto__;
    }
    return false;
}

console.log(instanceOf([], Array));
Copy the code

3, closures

(1) What is a closure?

Closures are nested functions within a function that have access to variables in the scope of another function.

(2) the execution process of JS code

After looking at the closure definition, we will understand the whole process of js code execution, as follows:

The whole execution process of JavaScript code is divided into two stages: code compilation stage and code execution stage. The compilation phase is done by the compiler, translating code into executable code, where scoping rules are determined. The execution phase is done by the engine and the main task is to execute executable code. The execution context is created in this phase.

(3) How to generate closures in general?

  • Functions are passed as return values
  • The function is returned as an argument

(4) The nature of closure generation

  • There is a reference to the parent scope in the current environment

(5) Characteristics of closures

  • Function nested inside function
  • Inner functions can refer to outer parameters and variables
  • Parameters and variables are not collected by the garbage collection mechanism

(6) Advantages and disadvantages of closures

  • Advantages: Encapsulation and caching can be realized.
  • Disadvantages: (1) memory consumption; (2) Improper use of memory overflow.

(7) Solutions

  • Before exiting the function, remove all unused local variables.

(8) Let closure

The let generates a temporary dead zone. In the current execution context, the variable is promoted but not initialized, so referring to the variable before it has been assigned by the executing code during context execution will raise an error because the variable is not initialized.

(9) Application scenarios of closures

  • The function is currified
  • The module

(10) Handwritten question: Function Coriolization

1) What is Corrification

Cremation means that there is A function that takes function A and returns A new function that can handle the rest of function A’s arguments.

2) Code implementation

The following three specific implementation methods are given, the code is as follows:

/** * Corrification: To change a function that takes more than one argument to a function that takes any argument and returns a function that takes any argument, so that the call can continue until the last call. Example: Add (1, 2, 3, 4, 5) returns 15. Now change it to something like add(1)(2)(3)(4)(5) or Add (1)(2, 3, 4)(5) and have the same function */

// The normal add() function
function add(){
    let sum = 0;
    let args = [...arguments];
    for(let i in args){
        sum += args[i];
    }
    return sum;
}

// The first type of add() is currified
// Disadvantages: The result returned is a function type, but is implicitly converted to a string, calling the toString() method

function add1(){
    // Create an array to store all parameters received later
    let args = [...arguments];

    function getArgs(){ args.push(... arguments);return getArgs;
    }

    getArgs.toString = function(){
        return args.reduce((a,b) = > {
            returna + b; })}return getArgs;
}

// The second way to currize the add() function
// Disadvantages: the call needs to be called again at the end, that is, the call with no parameters means that there are no arguments
function add2(){
    let args = [...arguments];

    return function(){
        // Add all the numbers when the length is 0
        if(arguments.length === 0) {return args.reduce((a,b) = > {
                returna + b; })}else{
            // Define an _args for traversal
            let _args = [...arguments];
            // Traversal is performed if the length is not 0
            for(let i = 0; i < _args.length; i++){
                args.push(_args[i]);
            }
            return arguments.callee; }}}// The third way to add() function currization
// Disadvantages: Set the total number of parameters to be passed before beginning to pass parameters
function add3(length){
    // Slice (1) indicates starting from the second element
    let args = [...arguments].slice(1);

    return function(){
        args = args.concat([...arguments]);
        if(arguments.length < length){
            return add3.apply(this, [length - arguments.length].concat(args));
        }else{
            // Return the desired destination
            return args.reduce((a,b) = >a + b); }}}// Test the code
let res = add(1.2.3.4.5);
let res1 = add1(1) (2) (3) (4) (5);
let res2 = add2(1) (2.3.4) (5) ();let res3 = add3(5);

console.log(res);
console.log(res1);
console.log(res2);
console.log(res3(1) (2.3) (4) (5));
Copy the code

(11) Supplementary

Detailed explanation of the article added πŸ‘‡

  • Analysis of scope and closure, analysis of function Coriolization
  • Links: juejin. Cn/post / 697046…

4. Variable objects

(1) Variable object

A variable object, which is a part of the execution context, can be abstracted as a data scope or can be understood as a simple object that stores all variables and function declarations (excluding function expressions) in the execution context.

(2) Active objects

Active Object (AO) : The variable object becomes active when its context is Active EC.

(3) Variable promotion

When a function runs, it first creates the execution context, then pushes the execution context onto the stack, and when the execution context is at the top of the stack, it starts running the execution context.

Three things are done during the creation of an execution context: Function (arguments); function (arguments); function (arguments); function (arguments); It then scans the var variable declaration and creates a property of the same name with the value undefined, which is called variable promotion.

Specific examples are given below:

js (b) //call b
console.log(a) //undefined
let a = 'Hello World';
function b(){
console.log('call b');
}
Copy the code
b(); // call b second 
function b() { 
    console.log('call b fist');
}
function b() { 
    console.log('call b second');
}
var b = 'Hello world';
Copy the code

😜 4. Events

1. Event model

The W3C defines events as occurring in three stages: capturing, targetin, and bubbling.

  • Bubble events: When you use event bubbles, child elements fire first and parent elements fire later.
  • Capture events: When you use event capture, the parent element fires first and the child element fires later.
  • DOMEvent flow: Supports both event models: capture and bubble events.

2. How are events implemented?

In a publish-subscribe model, event-related code is read when the browser loads, but not executed until a specific event is triggered.

Clicking a button, for example, is an Event, and the piece of code responsible for handling the Event is often called an Event Handler, which is the action of “initiating the display of the dialog box.”

On the Web side, we often see DOM events:

  • DOM0 level eventsDirectly inhtmlBinding on elementon-event, such asonclickIf you cancel it,dom.onclick = null.There can only be one handler for an eventThe back will cover the front.
  • Grade DOM2 eventsThrough theaddEventListenerRegistered event, passedremoveEventListenerAn event can have multiple event handlers, executed in sequence, capturing events and bubbling events.
  • Level the DOM3 event, added event types, such asUIEvent, focus event, mouse event.

3. How to add event monitor?

Listen for events via onclick and addEventListener.

4. What is event delegation?

(1) Definition

  • Event Delegation, also known as Event DelegationEvent delegation, it isJavascriptThat is commonly used inThe binding eventSkills.
  • “Event broker” refers to delegating the events that need to be bound to the parent element, so that the parent element acts as the event listener.

(2) Principle

  • The principle of event broker is as followsDOMElement events bubble up.

(3) Benefits

  • The advantage of using event brokers is that you can improve performance.
  • Can greatly save memory footprint and reduce event registration, such as inulOn agent ownedli ηš„ clickEvents.
  • It is possible to add a child object without binding it again.

(4) Supplement

Detailed explanation article supplement (event) πŸ‘‡

  • Do you really understand event binding, event bubbling, and event delegation?
  • Links: juejin. Cn/post / 697194…

5, Talk about the event loop

(1) Definition

First of all, JS is single-threaded, and its main task is to handle user interactions, which are nothing more than responding to DOM additions, deletions, and changes. How do you handle event responses?

The browser’s Web apis provide a separate running space for asynchronous code. When the asynchronous code is finished, the callback in the code is placed in a Task Queue. When the call stack is empty, the callback function in the Queue is pushed into the call stack. When the stack is empty and the task queue is empty, the call stack still checks whether there is any code in the task queue that needs to be executed. This process is a complete Event loop.

At the same time, it should be noted that the JS engine has priorities in the execution process. In an event cycle, the JS engine will first execute the main task of the JS thread, and then find whether there is a microtask (promise). If there is, the microtask will be executed first. Then go to the macrotask macrotask (setTimeout, setInterval) for execution.

(2) commonly used macro tasks and micro tasks

1) Commonly used macro tasks and micro tasks include:

The name of the Examples (commonly used)
Macro task Script, setTimeout, setInterval, setImmediate, I/O, UI Rendering
Micro tasks Process. NextTick (), Promise

Appeal setTimeout and setInterval are task sources, and the tasks they distribute really enter the task queue.

2) Priority

  • SetTimeout = setInterval A queue
  • setTimeout > setImmediate
  • process.nextTick > Promise
for(const macroTask of macroTaskQueue){
    // 2. Execute the macro task again
    handleMacroTask();
    for(const microTask of microTaskQueue){
        // 1. Perform the microtask firsthandleMicroTask(); }}Copy the code

(3) how long does setTimeout(fn,0) take to execute?

SetTimeout is queued in sequence and waits for the function call stack to clear before executing. The order in which these operations are queued is determined by the set delay time.

(4) Supplement

Detailed article supplement (event loop) πŸ‘‡

  • 参 考 θ―‘ ζ–‡1: Explain the application of queue in front end, take a deep look at Eventloop in JS, and then learn about micro task and macro task
  • Link 1: juejin.cn/post/696875…
  • Event Loop in browser and Node environment
  • Link 2: juejin.cn/post/688699…

πŸ€ͺ this question

1. Describe this object.

  • thisThe context in which a function is executed always points to the functionDirect caller(rather than an indirect caller), can be passedapply , call , bindchangethisPointing to.
  • If you havenewKey words,thisPoint to thenewThe object that came out.
  • In the event,thisPoint to the object that triggered the event, and in particular,IEIn theattachEventIn thethisAlways point to a global objectwindow 。
  • forAnonymous functionsorA function called directlySpeaking,thisPoint to theGlobal context(Browser:window ,NodeJS δΈΊ global), the rest of the function call, that’s who calls it,thisJust point to someone.
  • fores6The direction of the arrow function depends onThe position declared by the arrow functionWhere to declare,thisIt points to where.

2. Four rules for this binding

The four rules for the this binding follow the following order:

New Binding > Show Binding > Implicit Binding > Default binding

Here are the four rules.

(1) New binding

  • The New binding:newCalling the function creates a brand new object and binds this object to the function callthis 。NewBinding, if yesnewA hard-bound function, then will usenewThe new object replaces the hard bindingthis 。The specific implementation code is as follows:
function foo(a) { 
    this.a = a; 
}
var bar = new foo(2); 
console.log(bar.a); / / 2
Copy the code

(2) Explicit binding

  • According to the binding: by running on a functioncall ε’Œ applyTo display the bindingthis 。The specific implementation code is as follows:
function foo() { 
    console.log(this.a); 
}
var obj = { 
    a: 2 
};
foo.call(obj); / / 2
Copy the code
  • Shows the hard binding of the binding
function foo(something) { 
    console.log(this.a, something); 
    return this.a + something; 
}
function bind(fn, obj) { 
    return function() { 
        return fn.apply(obj, arguments); 
    }; 
}
var obj = { 
    a: 2 
}
var bar = bind(foo, obj);
Copy the code

(3) Implicit binding

  • Implicit binding: Whether the call location existsContext object, or whether it is owned or contained by an object, then the implicit binding rule will call the function inthisBind to this context object. Also, the object property chain is only at the upper or last levelThe positionPlay a role in.The specific implementation code is as follows:
function foo() { 
    console.log(this.a); 
}
var obj = { 
    a: 2.foo: foo, 
}
obj.foo(); / / 2
Copy the code

(4) Default binding

  • The default binding: No other modifiers (bind 、 apply 、 call), define pointing in non-strict modeGlobal objectTo define the pointing in strict modeundefined 。The specific implementation code is as follows:
function foo() { 
    console.log(this.a); 
}
var a = 2; 
foo(); //undefined
Copy the code

3. If a constructor binds an object, will the instance created using the constructor inherit its properties? Why is that?

No inheritance, because according to the four rules of this binding, the new binding takes precedence over the bind display binding. When a constructor call is made through new, a new object is created. This new object replaces bind’s object binding as this for this function, and in the case that this function returns no object, Returns the newly created object.

4. What is the difference between arrow functions and normal functions? Can arrow functions be constructors?

(1) Definition of arrow function and ordinary function

Normal functions are defined by the function keyword. This cannot be used with lexical scope and is bound at run time, depending only on how the function is called, where it is called, and where it is called. (depends on the caller, and whether it runs independently).

Arrow functions are defined using the operation => called the fat arrow. Instead of applying the four rules of the normal this binding, arrow functions determine this based on the outer (function or global) scope, and the binding of the arrow function cannot be modified (nor can new).

(2) Difference between arrow function and ordinary function

  • Arrow functions are often used in callback functions, including event handlers or timers.
  • The sum of arrow functionsvar self = thisAre trying to replace the traditionalthisThe operating mechanism willthisThe binding pulls backLexical scope.
  • No prototype, no prototypethis, nosuper, there is noarguments, there is nonew.target 。
  • Can’t passnewKeyword call.
    • There are two methods inside a function:[[Call]] ε’Œ [[Construct]], through thenewIs executed when a function call is made[[construct]]Method to create an instance object, and then execute the function body, will functionthisBind to this instance object.
    • Executes when called directly[[Call]]Method, directly executedThe body of the function.
    • Arrow function doesn’t have any[[Construct]]Method,Cannot be used as a constructor callWhen usingnewAn error occurs when making a function call.
function foo(){
    return (a) = > {
        console.log(this.a); }}let obj1 = {
    a: 2
};

let obj2 = {
    a: 3
};

let bar1 = foo.call(obj1);
let bar2 = bar1.call(obj2);

console.log(bar1); // object
console.log(bar2); // 2 undefind
Copy the code

5. What does apply, call, and bind mean?

(1) The differences among the three

  • apply 、call 、bindAll three are methods of the function, and all of them can change the functionthisPointing to.
  • apply ε’Œ callThey’re all changing functionsthisPoint to, and inIncoming parametersImmediately after the call to execute the function.
  • bindI’m changing the functionthisAfter pointing to, and passing in the argument returns a new function, not immediately called execution.

(2) Method of parameter transmission

The arguments passed in by apply are arrays, the arguments passed in by call are sequentially separated by commas, and the arguments passed in by bind are either arrays or sequentially. See below for details:

apply: 
Array.prototype.apply(this, [args1, args2]) ES6 is used to expand array calls, foo.apply(null, []), ES6 after use... The operator;call: 
Array.prototype.call(this, args1 args2).bind: 
Array.prototype.bind(this, args1 args2);Array.prototype.bind(thisArgs2], [args1).Copy the code

(3) Write apply, call and bind by hand

Apply:

// Implement the apply function, encapsulating myApply on the function prototype to achieve the same effect as the original apply function

Function.prototype.myApply = function(context){

    // Store the target object to be moved
    _this = context ? Object(context) : window;

    // Set a unique attribute on the object that passes this and assign the function to it
    let key = Symbol('key');
    _this[key] = this;

    // Call the function as an argument to separate the arguments stored in the array
    let res = arguments[1] ? _this[key](...arguments[1]) : _this[key]();

    / / delete
    delete _this[key];

    // Return the value returned by the function
    return res;
}

// Test the code
let obj = {
    'name': 'Joe'
}

function showName(first, second, third){
    console.log(first, second, third);
    console.log(this.name);
}

showName.myApply(obj, [7.8.9]);

Copy the code

The call:

// Implement the call function. Encapsulate the myCall function on the function prototype to achieve the same effect as the native call function

Function.prototype.myCall = function(context){

    // Store the target object to be moved
    let _this = context ? Object(context) : window;

    // Set a unique attribute on the object that passes this and assign the function to it
    let  key = Symbol('key');
    _this[key] = this;

    // Create an empty array to store multiple incoming parameters
    let args = [];

    // Add all the parameters passed to the new array
    for(let i =1; i < arguments.length; i++){
        args.push(arguments[i]);
    }

    // Pass the new array as multiple arguments and call the function
    letres = _this[key](... args);/ / delete
    delete _this[key];

    // Return the value returned by the function
    return res;
}

let obj = {
    'name': 'Joe'
}

function showName(first, second, third){
    console.log(first, second, third);
    console.log(this.name);
}

showName.myCall(obj, 7.8.9);

Copy the code

The bind:

Bind (myBind) {// Bind (myBind) {// Bind (myBind) {// Bind (myBind)

Function.prototype.myBind = function(context){

    // Store the target object to be moved
    let _this = context ? Object(context) : window;

    // Set a unique attribute on the object that passes this and assign the function to it
    let key = Symbol('key');
    _this[key] = this;

    // Create a function closure
    return function(){

        // Add all parameters to the new array in order to support the need for multiple parameters and array parameters
        letargs = [].concat(... arguments);// Call the function
        letres = _this[key](... args);/ / delete
        delete _this[key];

        // Return the value returned by the function
        returnres; }}// Test the code
let obj = {
    'name' : 'Joe'
}

function showName(first, second, third){
    console.log(first, second, third);
    console.log(this.name);
}

showName.myBind(obj)([7.8.9]);

Copy the code

πŸ˜‹ 6. Ajax issues

1. Ajax principles

  • AjaxIn simple terms, the principle ofThe userandThe serverI added one in betweenThe middle layer(AJAX engine), passXMLHTTPRequestObject makes an asynchronous request to the server, gets data from the server, and usesjavascriptTo operateDOMAnd update the page.
  • Asynchronize user actions and server responses. One of the most critical steps is getting the request data from the server.
  • AjaxThe process only involvesJavascript 、XMLHttpRequest ε’Œ DOM, includingXMLHttpRequest 是 ajaxCore mechanics.

Ajax to solve the browser cache problem

  • inajaxAdd before sending the requestanyAjaxObj.setRequestHeader("If-Modified-Since","0") 。
  • inajaxAdd before sending the requestanyAjaxObj.setRequestHeader("Cache-Control","no-cache") 。
  • inURLFollowed by a random number:"fresh=" + Math.random() 。
  • inURLAdd time after rub:"nowtime=" + new Date().getTime() 。

3, JS single thread

  • Single thread: Only one thread can do one thing.

  • Reason: Avoid DOM rendering conflicts.

    • The browser needs to renderDOM οΌ›
    • JSYou can modifyDOMStructure;
    • JSExecute when the browserDOMRendering will pause;
    • Two pieces ofJSNor can both be executed at the same timeDOMConflict);
    • WebworkerMultithreading is supported, but not accessibleDOM.
  • Solution: Asynchronous.

4. Implementation of asynchronous programming

(1) Callback function

  • Advantages: Simple and easy to understand
  • Disadvantages: Poor maintenance, high code coupling

(2) Event monitoring (time-driven mode, depending on whether an event occurs)

  • Advantages: Easy to understand, multiple events can be bound, and each event can specify multiple callback functions
  • Disadvantages: Event driven, process is not clear

(3) Publish/subscribe (Observer mode)

  • Similar to event monitoring, but with the “message center,” you can see how many publishers and subscribers there are

(4) Promise objects

  • Advantages: Can be usedthenMethod, carry onThe chain of writing; Can write error whenThe callback function;
  • Cons: Relatively difficult to write and understand

(5) Generator functions

  • Advantages: data exchange in and out of functions, error handling mechanism
  • Disadvantages: process management is not convenient

(6) Async function

  • Benefits: built-in actuators, better semantics, wider applicability, return isPromiseThe structure is clear.
  • Cons: Error handling mechanism

5. Js script loading problems, async and defer problems

  • If relying on other scripts andDOMResult, usedefer.
  • If theDOMAnd other script dependencies are not strong when usedasync.
  • Conclusion: Dependency is strongdeferDependency is not strongly usedasync 。

Window. onload and DOMContentLoaded

window.addEventListener('load'.function(){
    // The page will not be executed until all resources are loaded, including images, videos, etc
});

document.addEventListener('DOMContentLoaded'.function(){
    // Select this method when DOM rendering is complete
});
Copy the code
  • A supplement to DOM and BOM operations πŸ‘‡

  • To improve your understanding of the front-end, you have to understand the DOM and BOM of Web apis

  • Links: juejin. Cn/post / 697156…

7. Differences between Ajax, AXIos and FETCH

(1) the ajax

  • Itself is directed atMVCProgramming, do not conform to the present front-endMVVMThe wave.
  • primordialXHRThe development,XHRIts own architecture is not clear. It already existsfetchIs an alternative to.
  • JQueryThe whole project is too big for pure useajaxI’m going to introduce the wholeJQueryVery unreasonable (take personalized package scheme can not enjoyCDNServices).

(2) axios

  • Created from the browserXMLHttpRequest.
  • fromnode.jsahttpThe request.
  • supportPromise API 。
  • Intercept requests and responses.
  • Transform request and response data.
  • Cancel the request.
  • Automatic conversionJSONThe data.
  • Client support preventsCSRF/XSRF.

(3) the fetch

  • fetchThe returnedpromiseWill not be marked asrejectEven if thehttpThe status code of the response is404 ζˆ– 500. Is flagged only if the network fails or the request is blockedreject 。
  • Error only for network requests, yes400 , 500Are treated as successful requests that need to be wrapped and processed.
  • Here forcookieThe processing is special for different browser pairscredentialsIs not the same as the default value, which makes the defaultcookieIt becomes uncontrollable.
  • Come without its ownabortCannot timeout control, can be usedAbortControllerResolve cancellation request issues.
  • There is no way to monitor the progress of requests natively, whileXHRYou can.

8, handwriting: handwriting Ajax functions

/* 1. Get () method parameters: URL (request address), data (carry data), callback (success callback function), dataType (return data type) 2. Url (requested address), data (carrying data), callback (success callback function), dataType (return data type) Obj (objects containing various parameters), including URL, data, dataType, async, type */

let$= {createXHR: function() {
		if(window.XMLHttpRequest) {
			return new XMLHttpRequest()
		} else {
			return new ActiveXObject()
		} 
	},
	get: function(url, data, callback, dataType) {
		let dataType = dataType.toLowerCase()
		if(data) {
			url += '? '
			Object.keys(data).forEach(key= > url += `${key}=${data[key]}& `)
			url = url.slice(0, -1)}let xhr = this.createXHR()

		xhr.open('get', url)
		xhr.send()
		xhr.onreadystatechange = function() {
			if(xhr.readyState === 4) {
				if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
					let res = dataType === 'json' ? JSON.parse(xhr.responseText) : xhr.responseText
					callback(res, xhr.status, xhr)
				}
			}
		}
	},
	post: function(url, data, callback, dataType) {
		let dataType = dataType.toLowerCase()

		let xhr = this.createXHR()

		let str = ' '
		if(data) {
			Object.keys(data).forEach(key= > str += `${key}=${data[key]}& `)
			str = str.slice(0, -1)
		}
		xhr.setRequestHeader('Content-Type'.'application/x-www-form-urlencoded')
		xhr.send(str)
		xhr.onreadystatechange = function() {
			if(xhr.readyState === 4) {
				if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
					let res = dataType === 'json' ? JSON.parse(xhr.responseText) : xhr.responseText
					callback(res, xhr.status, xhr)
				}
			}
		}
	},
	ajax: function(params) {
		// Initialize parameters
		let type = params.type ? params.type.toLowerCase() : 'get'
		let isAsync = params.isAsync ? params.isAsync : 'true'
		let url = params.url
		let data = params.data ? params.data : {}
		let dataType = params.dataType.toLowerCase()

		let xhr = this.createXHR()
		
		let str = ' '
		
		// Concatenates a string
		Object.keys(data).forEach(key= > str += `${key}=${data[key]}& `)
		str = str.slice(0, -1)
		
		if(type === 'get') url += `?${str}`;

		return new Promise((resolve, reject) = > {
			// Create the request
			xhr.open(type, url, isAsync)

			if(type === 'post') {
				xhr.setRequestHeader('Content-Type'.'application/x-www-form-rulencoded')
				xhr.send(str)
			} else {
				xhr.send()
			}

			xhr.onreadystatechange = function() {
				if(xhr.readyState === 4) {
					if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
						let res = dataType === 'json' ? JSON.parse(xhr.responseText) : xhr.responseText
						resolve(res) // Request successful, data returned
					} else {
						reject(xhr.status) // Request failed, return status code}}}})}}Copy the code

9. Handwritten questions: Handwritten Promise principle

class MyPromise{
    constructor(fn){
        this.resolvedCallbacks = [];
        this.rejectCallbacks = [];
        
        // Pending is in the pending state
        this.state = 'PENDING';
        this.value = ' ';
        
        fn(this.resolve.bind(this), this.reject.bind(this));
    }

    resolve(value){
        if(this.state === 'PENDING') {this.state = 'RESOLVED';
            this.value = value;

            this.resolvedCallbacks.map(cb= >cb(value)); }}reject(value){
        if(this.state === 'PENDING') {this.state = 'REJECTED';
            this.value = value;

            this.rejectCallbacks.map(cb= >cb(value)); }}then(onFulfilled, onRejected){
        if(this.state === 'PENDING') {this.resolvedCallbacks.map(cb= > cb(onFulfilled));
            this.rejectCallbacks.map(cb= > cb(onRejected));
        }

        if(this.state === 'RESOLVED'){
            onFulfilled(this.value);
        }

        if(this.state === 'REJECTED'){
            onRejected(this.value); }}}Copy the code

10, handwritten question: based on the Promise handwritten promise.all

/** * Three states of promise: * 1. Pending: pending state, such as network request, or timer is not up; Reject discard discard discard discard discard discard discard discard discard discard discard discard discard discard discard discard discard
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
() / / function.
// The then function is a method in a Promise that calls the trigger when the Promise is in fulfill state
// Resolve and reject are function arguments passed in by default
new Promise((resolve, reject) = > {
    setTimeout(() = > {
        // Calling the resolve function in a Promise changes the Promise state to fulfill
        The resolve function can pass an argument as the default argument to the then function
        resolve('success');
    }, 1000);
})
.then(data= > {
    console.log(data); // The output is successful
});

/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ / function. The catch ()
// The catch function is a method of Promise. It invokes a trigger when a Promise is reject
new Promise((resolve, reject) = > {
    setTimeout(() = > {
        // Calling reject on a Promise changes the Promise state to reject
        The reject function can pass in a single argument as the default pass to the catch function
        reject('failure');
    }, 1000)
})
.catch(err= > {
    console.log(err); // Result output: failed
})

/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ / function. Finally ()
// The finally function is a method ina Promise that fires at the end of the Promise, no matter what state the Promise is in
new Promise((resolve, reject) = > {
    setTimeout(() = > {
       resolve('Success! ')},1000)
})
.then(data= > {
    console.log(data);
})
.finally(() = > {
    console.log('Promise to end');
})

/* Result output: success! Promise to end * /

/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ / function all ()
// The all function is a method in a Promise that wraps multiple Promise instances into a new Promise instance
Promise.all([
    new Promise((resolve, reject) = > {
        setTimeout(() = > {
            resolve('I'm the first asynchronously requested data');
        });
    }, 1000),
    new Promise((resolve, reject) = > {
        setTimeout(() = > {
            resolve('I'm the second asynchronously requested data');
        }, 1000);
    })
])
.then(results= > {
    console.log(results); // [' I am the data in the first asynchronous request ', 'I am the data in the second asynchronous request ']
})

/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
// Real application
let string1 = 'I am';
new Promise((resolve, reject) = > {
    setTimeout(() = > {
        let string2 = string1 + 'Monday';
        resolve(string2);
    }, 1000);
})
.then(data= > {
    return new Promise((resolve, reject) = > {
        let string3 = data + 'in CSDN';
        resolve(string3);
    })
})
.then(data= > {
    console.log(data);
})
.finally(() = > {
    console.log('Promise to end');
})

/* I am Monday in CSDN! Promise to end * /
Copy the code

Full explanation article supplement (Promise) πŸ‘‡

  • Nanny takes you step by step to fulfill the core promise features
  • Link: blog.csdn.net/weixin_4480…

πŸ₯° seven, handwriting supplement

1. Performance optimization

(1) Handwriting throttling function

Throttling: Performed at regular intervals, usually at high frequency triggers, to reduce the frequency. — such as: mouse slide, drag

In layman’s terms, throttling goes from triggering execution frequently to executing it every once in a while.

// Encapsulate the throttling function to implement throttling
function throttle(func, delay=500) {
    let timer = null;
    let status = false;

    return function (. args) {
        
        if(status) return;
        
        status = true;

        timer = setTimeout(() = > {
            func.apply(this, args)
            status = false}, delay); }}Copy the code

(2) handwritten anti – shake function

Anti – shake: trigger continuously for a period of time, do not execute, until the last time to execute beyond the specified time. — for example, input, scroll

In layman’s terms, anti – shake is executed only after frequent triggering.

// Encapsulate anti - shake function to achieve anti - shake
function denounce(func, delay=500){
    let timer = null;
    return function(. args){
        
        // If there is a value, clear the timer and continue
        if(timer){
            clearTimeout(timer);
        }

        timer = setTimeout(() = > {
            func.apply(this, args); },delay); }}Copy the code
  • Detailed article supplement (anti – shake throttling) πŸ‘‡

  • In terms of front-end performance optimization, we should understand the loading process of web pages and anti-shaking throttling

  • Links: juejin. Cn/post / 697306…

(3) lazy loading of pictures

Definition:

Lazy loading highlight a “lazy” word, lazy is delay the meaning of late, so “lazy loading” namely lazy loading, for example, we load a page, the page is very long, long to our browser viewing area to hold, so lazy loading is priority loading the content of the viewing area, the other part enters the viewing area in load.

Code implementation:

let img = document.getElementsByTagName('img'); // Get the img tag associated
let num = img.length; // Record how many images there are
let count = 0; // count from the first image

lazyload(); // Don't forget to load images for the first time

function lazyload() {
    let viewHeight = document.documentElement.clientHeight; // clientHeight gets the height of the visible area of the screen
    let scrollHeight = document.documentElement.scrollTop || document.body.scrollTop; // The height of the scroll bar
    for (let i = 0; i < num; i++) {
        // The element now appears in the visual area
        if (img[i].offsetTop < scrollHeight + viewHeight) {
            // When SRC does not exist, jump out of the loop and continue to the next round
            if (img[i].getAttribute('src')! = ='default.jpg') {
                continue;
            } else {
                // When the SRC attribute exists, get the value of SRC and assign it to img
                img[i].src = img[i].getAttribute('data-src'); count++; }}}}Copy the code
  • Detailed articles are added at πŸ‘‡
  • LazyLoad with native JS
  • Link: zhuanlan.zhihu.com/p/55311726

2. Native API handwriting

(1) the forEach

Usage:

The forEach() method performs the given function once on each element of the array. Native API details are as follows:

arr.forEach(function(currentValue, currentIndex, arr) {}, thisArg)

/ / currentValue required. The current element
/ / currentIndex optional. The index of the current element
/ / arr is optional. The array object to which the current element belongs.
ThisArg This parameter is optional. Used as the value of this when the callback function is executed.
Copy the code

Code implementation:

Array.prototype.myForEach = function (fn, thisArg) {
    if (typeoffn ! = ='function') {
        throw new Error('Arguments must be functions');
    }
    if (!Array.isArray(this)) {
        throw new Error('You can only use forEach on arrays');
    }
    let arr = this;
    for (let i = 0; i < arr.length; i++) { fn.call(thisArg, arr[i], i, arr); }}/ / test
let arr = [1.2.3.4.5];
arr.myForEach((item, index) = > {
    console.log(item, index);
});

/ / test thisArg
function Counter() {
    this.sum = 0;
    this.count = 0;
}

// Because thisArg argument (this) is passed to forEach(), it is passed to the callback function every time it is called as its this value
Counter.prototype.add = function (array) {
    array.myForEach(function (entry) {
        this.sum += entry;
        ++this.count;
    }, this);
}

const obj = new Counter();
obj.add([2.5.9]);

console.log(obj.count); // 3 === (1 + 1 + 1)
console.log(obj.sum); // 16 === (2 + 5 + 9)

Copy the code

(2) the map

Usage:

The map function processes each element in the array in turn and returns a new array, with no effect on the original array.

array.map(function(currentValue,index,arr){})
Copy the code

Code implementation:

Array.prototype.myMap = function (arr, mapCallback) {
    // Check if the parameters are correct
    if (!Array.isArray(arr) || !Array.length || typeofmapCallback ! = ='function') {
        return [];
    } else {
        let result = [];
        for (let i = 0; len = arr.length; i++) {
            result.push(mapCallback(arr[i], i, arr));
        }
        returnresult; }}/ / test
let arr = [1.2.3.4.5];
arr.map((item, index) = > {
    console.log(item * 2);
}); // 2, 4, 6, 8, 10
Copy the code

(3) filter

Usage:

The filter() method returns an array of items that execute true.

arr.filter(function(item, index, arr){}, context)
Copy the code

Code implementation:

Array.prototype.myFilter = function (fn, context) {
    if (typeoffn ! = ='function') {
        throw new Error(`${fn} is not a function`);
    }

    let arr = this;
    let temp = [];

    for (let i = 0; i < arr.length; i++) {
        let result = fn.call(context, arr[i], i, arr);
        // Check whether the condition is true
        if(result) { temp.push(arr[i]); }}return temp;
}

/ / test
let arr = [1.2.3.4.5.'A'.'B'.'C'];
console.log(arr.myFilter((item) = > typeof item === 'string')); // [ 'A', 'B', 'C' ]
Copy the code

(4) reduce

Usage:

  • Parameter: one callback function, one initialization parameter (optional)
  • The callback function argument has four values (res: represents the cumulative value,cur: Current value,index: Which number,arr: callreduceThe array)
  • The overall returnresAccumulated value
arr.reduce((res,cur, index, arr) = > res+cur, 0)
Copy the code

Code implementation:

/ * * * *@param {fn} Callback res→ represents the cumulative value, cur→ current value, index→ number of rows, arr→ array that calls reduce *@param {*} InitialValue (Optional) Initialization parameter */

Array.prototype.myReduce = function (cb, initValue) {
    if (!Array.isArray(this)) {
        throw new TypeError("not a array");
    }
    // The array is empty and has an initial value
    if (this.length === 0 && arguments.length < 2) {
        throw new TypeError('Reduce of empty array with no initial value');
    }
    let arr = this;
    let res = null;
    // Check whether there is an initial value
    if (arguments.length > 1) {
        res = initValue;
    } else {
        res = arr.splice(0.1) [0]; // If no, take the first value
    }
    arr.forEach((item, index) = > {
        res = cb(res, item, index, arr); // cb returns a new res value after each execution, overwriting the previous res
    })
    return res;
};

// Test results
let arr = [1.2.3.4];
let result = arr.myReduce((res, cur) = > {
    return res + cur;
})
console.log(result); / / 10
Copy the code

3, the rest of the handwritten questions

(1) Implementation of JSONP

JSONP principle: The appearance of JSONP makes script tag not subject to the same origin policy constraint, used for cross-domain requests, the advantage is good compatibility, the disadvantage is only used for GET requests.

const jsonp = ({ url, params, callbackName }) = > {
    const generateUrl = () = > {
        let dataSrc = ' ';
        for (let key in params) {
            if (params.hasOwnProperty(key)) {
                dataSrc += `${key}=${params[key]}& `;
            }
        }
        dataSrc += `callback=${callbackName}`;
        return `${url}?${dataSrc}`;
    }
    return new Promise((resolve, reject) = > {
        const scriptElement = document.createElement('script')
        scriptElement.src = generateUrl()
        document.body.appendChild(scriptElement)
        window[callbackName] = data= > {
            resolve(data)
            document.removeChild(scriptElement)
        }
    })
}
Copy the code

(2) the Object. The create

Usage:

Object.creat(Object [,propertiesObject]), used to create a new Object that inherits the properties of Object. The second parameter, propertyObject, is also an object and is an optional parameter that specifies a propertyObject for the newly created object. The property object may contain the following values:

attribute instructions
configurable Indicates whether the newly created object is configurable, that is, whether the properties of the object can be deleted or modified. The default is false
enumerable Object properties are enumerable, that is, enumerable. The default is false
writable Whether the object is writable and whether or not to add new attributes to the object. Default is false
get Object getter function, undefined by default
set Object setter function, undefined by default

Code implementation:

/ * * * *@param {*} Proto The prototype object of the newly created object *@param {*} PropertyObject The object for which enumerable properties or modified property descriptors are defined *@returns * /
Object.create2 = function (proto, propertyObject = undefined) {
    if (typeofproto ! = ='object' && typeofproto ! = ='function') {
        throw new TypeError('Object prototype may only be an Object or null.')}// Create an empty constructor F
    function F() {}// F prototype points to proto
    F.prototype = proto
    // Create an instance of F
    const obj = new F()
    // Call Object.defineProperties if propertiesObject has a value
    if(propertyObject ! =undefined) {
        Object.defineProperties(obj, propertyObject)
    }
    if (proto === null) {
        // Create an Object with no prototype Object, object.create (null)
        obj.__proto__ = null
    }
    // return this obj
    return obj
}

const person = {
    name: 'monday'.printIntroduction: function() {
        console.log(`My name is The ${this.name}, and my age is The ${this.age}`); }};const me = Object.create2(person);

me.name = 'Tuesday'; 
me.age = 18; 

me.printIntroduction();
  
Copy the code

(3) the Object. The assign

Usage:

The object.assign () method is used to assign the values of all enumerable properties from one or more source objects to target objects. It will return the target object.

Code implementation:

Object.assign2 = function (target, ... source) {
    if (target == null) {
        throw new TypeError('Cannot convert undefined or null to object');
    }
    let res = Object(target);
    source.forEach(function (obj) {
        if(obj ! =null) {
            for (let key in obj) {
                if(obj.hasOwnProperty(key)) { res[key] = obj[key]; }}}})return res;
}

const target = { a: 1.b: 2 };
const source = { b: 4.c: 5 };

const returnedTarget = Object.assign2(target, source);

console.log(target); // { a: 1, b: 4, c: 5 }

console.log(returnedTarget); // { a: 1, b: 4, c: 5 }
Copy the code

(4) Handwritten publishing and subscription

Code implementation:

class Subject {
    constructor(name) {
        this.name = name; // The name of the observed
        this.message = 'It's sunny today'; // Store a value
        this.observers = []; // Store all observers
    }

    on(observer) {
        this.observers.push(observer);
    }

    triggle(data) {
        this.message = data;
        this.observers.forEach(item= >item.update(data)); }}class Observer {
    constructor(name) {
        this.name = name;
    }
    update(newDate) {
        console.log('I'm an observerThe ${this.name}: ${newDate}`); }}// Test the code
let subject = new Subject('message');

let o1 = new Observer('little red');
let o2 = new Observer('Ming');

subject.on(o1); // I'm observer Xiao Hong: It's going to rain tomorrow
subject.on(o2); // I am an observer xiaoming: It will rain tomorrow

subject.triggle('It will rain tomorrow');
Copy the code

πŸ˜‰ 8. Conclusion

The above included all the JavaScript interview questions in the whole autumn recruitment preparation process on Monday, the above interview questions may not be complete, if you want to add content also welcome to vX :MondayLaboratory, I hope to make the article more perfect, benefit more preparation of friends ~

Finally, I wish you all the friends who read this article can get their favorite offer ~

🐣 Egg One More Thing

(: PDF content acquisition

πŸ‘‰ wechat public account Monday research room, click the navigation bar below to briefly view the keyword to obtain ~

(: Update address

πŸ‘‰ offer comes to the interview column

) Introduction

  • If you think this article is helpful to you, you might as well like to support yo ~~πŸ˜‰
  • That’s all for this article! See you next time! πŸ‘‹ πŸ‘‹ πŸ‘‹