There are two front-end routing modes: Hash mode and history mode

Why use routing

Single page application uses JavaScript to dynamically transform web content, avoiding page reloading. Routing allows the browser address to change, and the content of the page to follow, which combined to provide a well-experienced single-page Web application

Implementation of front-end routing

Routing needs to perform three functions

  • Switch pages when the browser address changes
  • Click the browser [Back], [Forward] button, the content of the web page to follow the change
  • The browser is refreshed, and the web page loads the current route

Route switching can be implemented in two ways

  • Hash mode: Monitors the hash value change of the browser address and executes the corresponding JS to switch the web page.
  • History mode: use the history API to change the URL address and change the web content;

The most obvious difference is that hash adds a # to the browser address, while history allows you to customize the address

Hash pattern

Using the window.location.hash attribute and the onHashchange event of the window, you can monitor the hash value of the browser address and execute the corresponding JS to switch the web page. Here are some key points you must understand in the process of using:

1. Hash refers to the # and the character that follows the address, also known as the hash value. Hashes, also known as anchors, are themselves used to navigate pages. Such as http://localhost/index.html#abc, the # of ABC is to hash;

The hash value is not sent to the server with the request, so changing the hash does not reload the page.

3. Listen for the window hashchange event. When the hash value changes, you can use location.hash to get and set the hash value.

4. Changes in the location.hash value are directly reflected in the browser address bar.

// To hash the URL, add '# ABC 'window.location.hash=' ABC' after the current URL; Let hash = window.location.hash //'# ABC 'window.adDeventListener ('hashchange',function(){// To listen for hash changes, clicking browser forward or back will trigger})Copy the code

The history mode

An overview of the

The window.history property points to the history object, which represents the browsing history of the current window. When changes are made, only the path of the page is changed, not the page is refreshed.

2. The History object holds the url of all pages visited by the current window. History. length shows how many urls the current window has visited.

3. For security reasons, browsers do not allow scripts to read these addresses, but do allow navigation between them.

4. The “Forward” and “Back” buttons on the browser toolbar actually operate on the History object.

attribute
  • History.length: Number of urls visited by the current window (including the current page)
  • History.state: state value at the top of the History stack (see below)
methods
  • History.back() : Move to the previous url, equivalent to hitting the browser’s back button. This method has no effect on the first url visited.
  • History.forward() : Moves to the next url, equivalent to clicking the browser’s forward button. This method has no effect on the last url visited.
  • History.go() : takes an integer as an argument and moves to the url specified by the argument, based on the current url. If the parameter exceeds the actual url range, the method has no effect. If no parameter is specified, the default parameter is 0, which means refreshing the current page

The method to change history.state is history.pushState(), which is used to add a record to history. The pushState() method does not trigger a page refresh, but only causes the History object to change and the address bar to change

var data = { foo: 'bar' }; 
history.pushState(data, '', '2.html'); 
console.log(history.state) // {foo: "bar"}
Copy the code

The history.replacestate method is used to modify the current record of the history object, as is the pushState() method.

history.pushState({page: 2}, '', '? page=2'); / / URL displayed as http://example.com/example.html?page=2 history. ReplaceState ({3} page: "', '? Page = 3); / / URL displayed as http://example.com/example.html?page=3Copy the code

Popstate The popState event is emitted every time the History object changes

Window.addeventlistener (' popState ', function(e) {//e.state equals history.state console.log('state: ' + JSON.stringify(e.state)); console.log(history.state); });Copy the code

Flex: 0, 1, auto what does each value represent

The Flex attribute is a contraction of the flex-grow, Flex-shrink, and Flex-basis attributes.

Flex-grow: defines the scale of the project;

  • The default value is 0, that is, it will not be enlarged even if there is free space.
  • Flex-grow for all projects is 1: evenly divide the remaining space (auto zoom space placeholder);
  • An item with flex-grow of N takes up n times as much space (magnification ratio) as an item with Flex-grow of 1.

Flex-shrink: defines the shrink of a project;

  • The default is 1, which means that the project shrinks if there is insufficient space;
  • The flex-shrink value is 1 for all projects: when space is insufficient, the amount of shrink is the same.
  • If flex-shrink is 0, the project does not shrink when space is insufficient.
  • A flex-shrink of N will shrink n times as much when space is insufficient as a Flex-shrink of 1.

Flex-basis: defines the main size of the project before allocating extra space. The browser uses this property to calculate whether there is extra space on the main axis.

  • The default value is auto, the original size of the project;
  • After setting, the project will occupy a fixed space.

So the default value of the Flex property is 0 1 auto: 0 0 auto: 1 1 auto: 0 0

Flex: 1 is used as an adaptive layout for display: flex. When the size of the display: flex sidebar is fixed, flex: 1 will automatically enlarge the content area to fill up the remaining space

Load balancing, first using DNS service to allocate a healthy Nginx server, and then to the corresponding Web server

0.1 + 0.2 = = = 0.3? why

When the two numbers are added, the mantissa will be converted to binary first. When 0.1 and 0.2 are converted to binary, the mantissa will have an infinite loop, and then the order calculation will be carried out. JS engine truncates binary, resulting in loss of accuracy.

So to sum up: precision loss may occur in base conversion and logarithmic operation

How to solve:

What’s the difference between an arrow function and a normal function? Can arrow functions be constructors?

  • 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 what is called the “fat arrow” operation =>. Arrow functions do not apply the four rules of the normal function this binding, but determine this based on the outer (function or global) scope, and the binding of the arrow function cannot be modified (nor can new).

    • Arrow functions are often used in callback functions, including event handlers or timers

    • The arrow function and var self = this both attempt to replace the traditional this mechanism by pulling the this binding back into lexical scope

    • No archetypes, no this, no super, no arguments, no new.target

    • Cannot be called by the new keyword

      • A function has two methods inside it: [[Call]] and [[Construct]]. When a function Call is made from new, the [[Construct]] method is executed to create an instance object, and then the function body is executed to bind the function’s this to the instance object
      • When called directly, the [[Call]] method executes the function body directly
      • The arrow function has no [[Construct]] method and cannot be used as a constructor call. An error is reported when a function call is made using new.
function foo() {
  return (a) => {
    console.log(this.a);
  }
}

var obj1 = {
  a: 2
}

var obj2 = {
  a: 3 
}

var bar = foo.call(obj1);
bar.call(obj2);
Copy the code

Q: If a constructor binds an object, does the instance created using the constructor inherit the object’s 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

Q: Ever used TypeScript? What does it do?

Adding type support to JS and providing support for the latest version of ES syntax is great for team collaboration and troubleshooting for large projects

Q: Is arguments an array in a function? Class array to array method understand?

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

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

Q: What functions can arrays call?

  • push
  • pop
  • splice
  • slice
  • shift
  • unshift
  • sort
  • find
  • findIndex
  • Map/Filter/Reduce and other functional programming methods
  • There are also some methods on the prototype chain: toString/valudOf

Q: How do YOU tell if an object is empty?

Object.keys(obj).length === 0

Q: What is NaN, and what will typeof output be?

Typeof NaN === ‘Number’ typeof NaN === ‘Number’

Do you know the Class of ES6? Static Static

Add methods directly to the function object of this class, rather than to the prototype of the function object

What’s the difference between a Node event loop and a browser event loop?

(1) Execution sequence of macro tasks:

Timer 2. Pending Callback: Indicates that the I/O callback is delayed until the next event loop. Idle, prepare: indicates that the callback is used internally only. 5. Check: setImmediate() 6. Close Callback Soke.on ('close', () => {})Copy the code

(2) The execution sequence of macro task and micro task in Node:

Node V10 (1) performs all tasks in a phase, (2) performs the contents of the nextTick queue, and (3) performs the contents of the microtask. Node V10 is now consistent with browser behaviorCopy the code

What do you know about event capture and bubbling?

(1) Basic concept: capture: top-down bubbling: bottom-up (2) Window. AddEventListener listens to what stage of events? Window.addeventlistener ('click', () => {}, false/true) False is the bubble phase /true is the capture phaseCopy the code

When container elements and nested elements call event handlers in the capture phase and in the bubble phase: Events execute event handlers in the order of the DOM event flow, and when the event is in the target phase, the order of event invocation depends on the order in which the binding events are written, as in the above example, calling the event handler in the bubble phase before calling the event handler in the capture phase. Alert “subset bubbling” and “subset capture” in turn.

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 events, which bind on-events directly to HTML elements, such as onclick. If you cancel, dom.onclick = null, you can only have one handler for an event, and the latter will override the previous one.

  • Dom2-level events, events are registered with addEventListener and removed with removeEventListener. An event can have multiple event handlers, executed in sequence, capturing events and bubling events

  • DOM3 level events, added event types, such as UI events, focus events, mouse events

Have you ever paid attention to front-end memory?

1. Memory life cycle? Memory allocation Memory usage Memory reclamationCopy the code

Front-end optimization

1. Load only the required resources

  • Asynchronously load components, lazily load images, polyfill

2. Reduce the size of your resources

  • Packing compression

  • Disengage from common resources

  • gzip

  • Try to control the size of cookies

  • Image format optimization, compression (PNG can be lossless compression), WebP

3. Timing optimization

  • Promise. all Concurrent requests

  • SSR pages can be cached on the server

  • prefetch, prerender, preload

JS related

Native array methods

The stack method

The push method takes one or more parameters, appends them to the end of an array, and returns the modified length of the array.

The pop method removes the last item of the array, subtracts the array length by one, and returns the removed item.

Queue method

The shift method removes the first item of the array, decreases the array length by one, and returns the removed item.

The unshift method can also take one or more parameters, append them in turn to the front of the array, and return the modified array length

Reorder method

The Reverse method is used to reverse an array.

The sort method, by default, sorts each item in an array in ascending order, with the smallest value coming first. But the sort method calls the toString method to compare each item to a string (strings are sorted by Unicode points), so this comparison scheme is not optimal in most cases. Such as:

var arr = [1, 3, 2, 5, 4]; arr.sort(); 
console.info(arr); // [1, 2, 3, 4, 5] 
arr = [1, 5, 10, 20, 25, 30]; 
arr.sort(); 
console.info(arr); // [1, 10, 20, 25, 30, 5]
Copy the code

Therefore, the sort method can take a comparison function as an argument and let us decide the sort rules. The comparison function takes two arguments, returning a negative number if the first argument is less than the second (that is, the first argument should precede the second), 0 if the two arguments are equal, and a positive number if the first argument is greater than the second

var arr = [1, 5, 10, 20, 25, 30]; arr.sort(function(value1, value2){ if(value1 < value2) { return -1; } else if(value1 > value2) { return 1; } else { return 0; }}); console.info(arr); // [1, 5, 10, 20, 25, 30]Copy the code
Operation method

The concAT method combines multiple arrays into a new array. Concat can accept either array or non-array values. Instead of manipulating an array, the concAT method creates a new array. It then places each item in the object that called it and each item in the argument or non-array argument in turn into the new array and returns the new array

The Slice method makes a shallow copy of some of the elements in the source array, returning a new array containing elements from the beginning to the end (excluding the end position). The Slice method also does not operate on the array itself, but instead copies each element of the original array into the newly created array. The copying process is the same as the concat method.

Splice Method The splice method is used to delete or modify array elements. Receive three parameters

  • The location of the first element to delete
  • Number of items to delete
  • The element to be inserted. You can add more parameters if you want to insert multiple elements
var arr = ['a', 'b', 'c', 'd', 'e']; var temp = arr.splice(2, 0, 'x', 'y', 'z'); console.info(arr); // ["a", "b", "x", "y", "z", "c", "d", "e"] console.info(temp); // [], the element is not deletedCopy the code

Location method

IndexOf() lastIndexOf() both methods take two arguments: Only indexOf() looks backwards from the beginning of the array (position 0), and lastIndexOf() looks forwards from the end of the array, returning the position of the item in the array, or -1 if it is not found. Use the congruent operator to compare and find.

An iterative approach

Every () : Runs the given function on each item in the array, and returns true if the function returns true for each item. Filter () : Returns an array of items that return true by running the given function on each item in the array. ForEach () : Runs the given function on each item in the array. This method returns no value. Map () : Runs the given function on each item in the array, returning an array of the results of each function call. Some () : Runs the given function on each item in the array, returning true if the function returns true for any item. None of the above methods modify the values contained in the array. Each method takes two parameters: the function to run on each item and the (optional) scoped object to run the function — which affects the value of this. The functions passed into these methods take three arguments: the value of the array item, the position of the item in the array, and the array object itself. 9. Merge method

Reduce () reduceRight() both methods iterate over all the items in the array and then build a value that is ultimately returned. Here, the reduce() method starts at the first entry of the array and iterates through to the end. ReduceRight (), on the other hand, starts from the last item of the array and traverses forward to the first item.

Both methods accept two parameters: a function called on each item and (optionally) the initial value as the basis for merging. The functions passed to reduce() and reduceRight() take four arguments: the previous value, the current value, the item’s index, and an array object. Any value returned by this function is automatically passed to the next item as the first argument. The first iteration occurs on the second item of the array, so the first argument is the first item of the array, and the second argument is the second item of the array.

Example:

Var values = [1, 2, 3, 4, 5]; var sum = values.reduce(function(prev, cur, index, array){ return prev + cur; }); console.log(sum); / / 15Copy the code

Method to determine if it is an array

The instanceof operator checks whether Array is an instanceof it

let arr = [];
console.log(arr instanceof Array); // true
Copy the code

2, arr.constructor === Array

let arr = [];
console.log(arr.constructor === Array); // true
Copy the code

3. Usage: Array. The prototype. IsPrototypeOf (arr) Array. The prototype attribute indicates the prototype of the Array constructor One of the method’s isPrototypeOf () is used to test whether an object exists in another object on the prototype chain.

let arr = [];
console.log(Array.prototype.isPrototypeOf(arr)); // true
Copy the code

Object.getprototypeof (arr) === array.prototype Object.getProtoTypeof () returns the prototype of the specified Object

So just compare it to Array’s prototype

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

Copy the code

5, usage: Object. The prototype. ToString. Call (arr) = = = ‘[Object Array]’

Although Array also inherits from Object, JS overrides toString on Array.prototype, whereas toString.call(arr) is actually called through the prototype chain

let arr = [];
console.log(Object.prototype.toString.call(arr) === '[object Array]'); // true
Copy the code

IsArray (ARR) ES5 adds the array. isArray method, which is not supported by Internet Explorer 8 or below

Array.isArray (arg) isArray takes one argument, arg, and returns true if the argument is an object and the class internal property is “Array”; Otherwise it returns false. Take the following steps: If Type(arg) is not Object, return false. Returns true if arG’s [[Class]] internal attribute value is “Array”. Returns false.

let arr = [];
console.log(Array.isArray(arr)); // true
Copy the code

A method to remove the weight of an array

1, double cycle weight reduction

Double for loop is a cumbersome method and its implementation principle is to create a new array containing the original array first, and then traverse the original array, each element from the original array and compare the new each element of the array, if you don’t repeat is added to the new array, finally return to the new array, if the length of the array is very big, so will be a great memory

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } let res = [arr[0]] for (let i = 1; i < arr.length; i++) { let flag = true for (let j = 0; j < res.length; j++) { if (arr[i] === res[j]) { flag = false; break } } if (flag) { res.push(arr[i]) } } return res }Copy the code

IndexOf (1)

The indexOf() method returns the first occurrence of the specified element in the array. This method first defines an empty array and then calls indexOf to traverse the original array. If the element is not in res, it is pushed into res

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } let res = [] for (let i = 0; i < arr.length; i++) { if (res.indexOf(arr[i]) === -1) { res.push(arr[i]) } } return res }Copy the code

3, indexOf method to remove 2

IndexOf is used to check whether the first occurrence position of an element in the array is the same as the current position of the element. If not, the element is a duplicate element

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } return Array.prototype.filter.call(arr, function(item, index){ return arr.indexOf(item) === index; }); }Copy the code

4. Adjacent elements are deduplicated

This method first calls sort(), and then traverses and aligns adjacent elements based on the sorted result. If they are equal, the elements are skipped until the traversal is complete

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } arr = arr.sort() let res = [] for (let i = 0; i < arr.length; i++) { if (arr[i] ! == arr[i-1]) { res.push(arr[i]) } } return res }Copy the code

5. Use object attributes to remove weight

Create an empty object, iterate through the array, set the value in the array to an attribute of the object, and assign the initial value of the attribute 1. Each occurrence increases the corresponding attribute value by 1, so that the attribute value corresponds to the number of occurrences of the element

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } let res = [], obj = {} for (let i = 0; i < arr.length; i++) { if (! obj[arr[i]]) { res.push(arr[i]) obj[arr[i]] = 1 } else { obj[arr[i]]++ } } return res }Copy the code

6. Set and structure assignment are de-duplicated

The data type set is new in ES6. One of the biggest features of a set is that data does not duplicate. The Set function can take an array (or array-like object) as an argument to initialize, which can also be used to deduplicate arrays

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } return [...new Set(arr)] }Copy the code

7, Array. From set

The array. from method converts a Set structure into an Array result, and we know that the Set result is a non-repeating data Set, so it can be de-duplicated

function unique(arr) { if (! Array.isArray(arr)) { console.log('type error! ') return } return Array.from(new Set(arr)) }Copy the code

Several ways to traverse a number set

1. ForEach loop

The most commonly used array traversal method provides a callback function that takes the first element in the current loop, the second element’s index, and the third array itself. All three parameters are optional. By default, no value is returned

2. Map method

A map, literally, is a map, a map of array elements. It provides a callback function that takes, optionally, the element in the current loop, its subscript, and the array itself. By default, an array is returned. Each element of the new array is the return value of the original array element after the callback

3. Filter method

Filter: a conditional filter on an array element. It provides a callback function that takes, optionally, the element in the current loop, its subscript, and the array itself. By default, an array is returned. If the value of the element returned by the callback is true, the element will be placed in the returned array

4, some, every method

The some method is used in much the same way as every, providing a callback to the element in the current loop, its index, and the array itself.

Each element of the array executes a callback, and every returns true when all of the values are true, and false whenever one of them is false. Some returns true when one of them is true, and every returns false when all are false.

The some and every methods do not alter the array

5. Reduce method

The reduce method takes two parameters, the first is a callback function (required) and the second is an initial value (optional). The callback takes the cumulative value of the loop, the element of the current loop (required), the element’s subscript (optional), and the array itself (optional).

The reduce method executes a callback for each element of the array, starting the next loop with the value returned from the previous callback, and finally returning the result.

If there is no initial value, reduce takes the first element of the array as the initial value to start the loop, and the second element starts the callback function.

The most common and simplest scenario is the accumulation and multiplication of array elements

6, for of method

Es6 adds the concept of interator interface to provide a unified access mechanism for all data structures, namely for of.

That is, all data with interator interface can be traversed using for of. Common ones include arrays, class arrays, sets, maps, etc., all of which have interator interfaces.

Js data types, Typeof, Instanceof, type conversions

  1. String, number, Boolean, null, undefined, object(function, array), symbol(ES10 BigInt)
  2. typeofMainly used to determine the data type of the return valueString, Boolean, number, function, object, undefined.
  3. instanceofDetermines whose instance the object is.
  4. nullRepresents an empty objectundefinedRepresents a variable declared in scope but not assigned

Typeof principle

When js stores variables at the bottom, it stores their type information 👉 in the lowest 1-3 bits of the variable’s machine code

  • 000: object
  • 010: floating point number
  • 100: string
  • 110: Boolean
  • 1: the integer

But, for undefined and NULL, the information storage for these two values is a bit special.

Null: All machine codes are 0

Undefined: it is an integer of −2^30

The machine code of null is zero, and therefore is treated as an object. Therefore, when using typeof to determine the typeof a variable, we need to pay attention to the following: It is best to use Typeof to determine base data types (including symbol) and avoid null

There is also a good type of method, is the Object. The prototype. ToString, we can use this method to a variable of type to compare accurate judgment

Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call('hi') // "[object String]" Object.prototype.toString.call({a:'hi'}) // "[object Object]" Object.prototype.toString.call([1,'a']) // "[object Array]" Object.prototype.toString.call(true) // "[object Boolean]" Object.prototype.toString.call(() => {}) // "[object Function]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object  Undefined]" Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"Copy the code

Instanceof principle

function new_instance_of(leftVaule, rightVaule) { let rightProto = rightVaule.prototype; // Take the prototype value of the right expression leftVaule = leftvaule.__proto__; While (true) {if (leftVaule === null) {return false; } if (leftVaule === rightProto) { return true; } leftVaule = leftVaule.__proto__ } }Copy the code

In fact, the main implementation principle of Instanceof is as long as the right variable’s prototype is on the left variable’s prototype chain. Thus, instanceof iterates through the prototype chain of the left variable until it finds the prototype of the right variable. If the lookup fails, it returns false, telling us that the left variable is not an instanceof the right variable.

Array flattening

flat

Arr. Flat (Infinity) // Reduce the dimensions of InfinityCopy the code
const numbers = [1, 2, [3, 4, [5, 6]]];
// Considers default depth of 1
numbers.flat(); 
> [1, 2, 3, 4, [5, 6]]
// With depth of 2
numbers.flat(2); 
> [1, 2, 3, 4, 5, 6]
// Executes two flat operations
numbers.flat().flat(); 
> [1, 2, 3, 4, 5, 6]
// Flattens recursively until the array contains no nested arrays
numbers.flat(Infinity)
> [1, 2, 3, 4, 5, 6]
Copy the code

reduce

Iterate over each item of the group, recursively if the value is array, otherwise concat

function flatten(arr) { return arr.reduce((result, item)=> { return result.concat(Array.isArray(item) ? flatten(item) : item); } []); }Copy the code

Reduce is a method of an array that takes a function as an accumulator, and each value in the array (from left to right) begins to shrink and eventually computes to a value. Reduce takes two arguments: the callback function, passed to the initial value of Total

Arr. Reduce ((total, item)=> {return total + item; }, 0);Copy the code

toString & split

Call the toString method of the array, turn the array into a string and then split it back into an array

function flatten(arr) { return arr.toString().split(',').map(function(item) { return Number(item); })}Copy the code

Because each item in a split array is a string, you need to use a map method to traverse the array to convert each item to a numeric value

Join & split Like toString above, a join can convert an array to a string

function flatten(arr) { return arr.join(',').split(',').map(function(item) { return parseInt(item); })}Copy the code

recursive

Each item is iterated recursively, continuing if it is an array, concat otherwise

function flatten(arr) { var res = []; arr.map(item => { if(Array.isArray(item)) { res = res.concat(flatten(item)); } else { res.push(item); }}); return res; }Copy the code

Extended operator

Es6’s extension operator turns a two-dimensional array into a one-dimensional one

[].concat(... [1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]Copy the code

Based on this result we can do a traversal, using the extension operator once if the ARR contains an array, until there is none left.

function flatten(arr) { while(arr.some(item=>Array.isArray(item))) { arr = [].concat(... arr); } return arr; }Copy the code

conclusion

Although there are five methods, there is only one core:

Iterate over the array arr, recursively if arr[I] is an array, until arr[I] is not an array and concat the previous result

Closure (high frequency)

A closure is a function that has access to a variable in another function’s scope.

Closures occur when a function can remember and access its lexical scope,

Even if the function is executed outside the current lexical scope — JavaScript you Don’t Know

Closures = functions + free variables that functions can access

In ECMAScript, closures refer to:

  1. From a theoretical point of view: all functions. Because they both store the data of the upper context at the time of creation. This is true even for simple global variables, since accessing a global variable in a function is equivalent to accessing a free variable, using the outermost scope.

  2. As a practical matter, the following functions are closures:

    1. It persists even if the context in which it was created has been destroyed (for example, an inner function returns from a parent function)
    2. Free variables are referenced in the code
  • Closure purpose:

    1. The ability to access the lexical scope in which a function is defined (preventing it from being recycled)
    2. Privatization variable
    3. Simulate block-level scopes
    4. Create a module
  • Disadvantages of closures: Function variables can be kept in memory, and too many closures can cause memory leaks

Prototype, prototype chain (high frequency)

Prototype: Each function has a Prototype property. The function’s Prototype property points to an object that is the prototype of the instance created by calling the constructor

Proto: This is a property that every JavaScript object (except null) has, called __proto__, which points to the object’s prototype

Constructor: Each stereotype has a constructor property pointing to the associated constructor

Prototype: The __proto__ property inherent in an object that points to the prototype property of the object. Every JavaScript object (except null) is associated with another object when it is created. This object is called a prototype, and every object “inherits” properties from the prototype.

Prototype chain: When we access a property of an object, if the property does not exist inside the object, it will look for the property in its prototype object, which in turn will have its own prototype, and so on and so on, consisting of multiple prototype chains. The end of the prototype chain is usually Object.prototype, so that’s why our new Object can use methods like toString().

Features: JavaScript objects are passed by reference, and each new object entity we create does not have a copy of its own prototype. When we modify the stereotype, the objects associated with it inherit the change.

This refers to the new keyword

This object is an attribute in the execution context that refers to the object on which the method was last called. In global functions, this equals window, and when the function is called as an object, this equals that object. In real development, the direction of this can be determined by four invocation patterns.

  1. Function calls, when a function is called directly as a function that is not a property of an object,thisPoints to a global object.
  2. Method call, if a function is called as a method of an object,thisPoint to this object.
  3. Constructor call,thisPoint to thisnewNewly created object.
  4. The fourth isApply, call and bindAll three methods can display the this pointer to the specified calling function.applyThe parameters are arrays,callAccept a list of arguments, ‘bind’Method returns an object by passing in an object this A new function that binds the passed object. Of this functionthisPoint to besides useIt will be changed when it’s new, and it won’t be changed otherwise.

new

  1. First, a new empty object is created
  2. Sets the prototype of the object to functionprototypeObject.
  3. Let the function of thethisPoint to the object and execute the constructor code (add attributes to the new object)
  4. Determine the return value type of the function and, if it is a value type, return the created object. If it is a reference type, an object of that reference type is returned.

Handwritten implementation

function create() { 
    let obj = {}; 
    let Con = [].shift.call(arguments); 
    obj.__proto__ = Con.prototype; 
    let result = Con.apply(obj, arguments); 
    return result instanceof Object ? result : obj; 
}
Copy the code
  • In the case of objects, everything is actually generated by new, whether function Foo() or let a = {b: 1}.

  • For creating an object, it is more recommended to create objects in a literal manner (both for performance and readability). Because you use new Object() to create objects you need to find them layer by layer through the scope chain, but you don’t have this problem with literals

Function Foo() {} // function Foo() {// function Foo() {// function Foo() {// function Foo();Copy the code

Scope, scope chain, variable promotion

Scope chain: When a variable is searched, it is first searched from the variable object of the current context. If it is not found, it is searched from the variable object of the execution context of the parent (lexical parent) until it finds the variable object of the global context, that is, the global object. Thus a linked list of variable objects in multiple execution contexts is called a scoped chain.

Scope chain creation process – Function activation: Take the following functions as an example

var scope = "global scope";
function checkscope(){
    var scope2 = 'local scope';
    return scope2;
}
checkscope();
Copy the code

1, the checkScope function is created to save the scope chain to the inner property [[scope]]

checkscope.[[scope]] = [
    globalContext.VO
];
Copy the code

2, execute the checkScope function, create the checkScope execution context, checkScope execution context is pushed into the execution stack

ECStack = [
    checkscopeContext,
    globalContext
];
Copy the code

Create a scope chain by copying the [[scope]] property of the function

checkscopeContext = {
    Scope: checkscope.[[scope]],
}
Copy the code

Step 2: Use arguments to create the active object, and then initialize the active object by adding parameters, function declarations, and variable declarations

CheckscopeContext = {AO: {arguments: {length: 0}, scope2: undefined}, Scope: checkScope.[[Scope]],}Copy the code

Step 3: Press the live object to the top of the CheckScope chain

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: undefined
    },
    Scope: [AO, [[Scope]]]
}
Copy the code

6. Start executing the function. As the function executes, modify the AO attribute values

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: 'local scope'
    },
    Scope: [AO, [[Scope]]]
}
Copy the code

When scope2 is returned, the function is executed and the function context is ejected from the execution context stack

ECStack = [
    globalContext
];
Copy the code

Variable to create

That’s it for creating variable objects. Let’s briefly summarize what we said above:

  1. The variable object initialization of the global context is the global object
  2. Function context variable object initializations include only Arguments objects
  3. Initial attribute values such as parameters, function declarations, and variable declarations are added to variable objects when entering the execution context
  4. During code execution, the attribute values of the variable object are modified again

Inheritance (including ES6), multiple inheritance modes

(1) The first is to implement inheritance in the way of prototype chain.

function Parent () {
    this.name = 'kevin';
}

Parent.prototype.getName = function () {
    console.log(this.name);
}

function Child () {
}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName()) // kevin
Copy the code

Disadvantages:

Properties of reference types are shared by all instances

2. When creating an instance of Child, do not pass an argument to Parent

(2) The second method is to use the borrowed constructor method, which is realized by calling the constructor of the supertype in the function of the subtype. This method solves the disadvantage of not passing parameters to the supertype, but it has one problem is that it cannot realize the reuse of function methods. And the method subtypes defined by the supertype stereotype are not accessible.

function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {
    Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]
Copy the code

Advantages:

1. Avoid the attribute of reference type being shared by all instances

2. You can pass parameters to Parent in Child

(3) The third method is combinatorial inheritance, which is a way to use a combination of stereotype chains and borrowed constructors. Inheritance of attributes of a type is achieved by borrowing constructors, and inheritance of methods is achieved by setting the stereotype of a subtype to an instance of a supertype. This solves the problem of using the two patterns separately, but since we prototyped the subtype using an instance of the supertype, we called the superclass constructor twice, resulting in many unnecessary attributes in the subtype stereotype.

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {

    Parent.call(this, name);
    
    this.age = age;

}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]
Copy the code

(4) The fourth way is the original type inheritance, the main idea of the original type inheritance is to create a new object based on the existing object, the principle of implementation is to pass an object to the function, and then return an object with this object as the prototype. The idea of inheritance is not to create a new type, but to implement a simple inheritance of an Object. The object.create () method defined in ES5 is an implementation of the original type inheritance. The disadvantage is the same as the prototype chain approach.

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}
Copy the code

(5) The fifth method is parasitic inheritance. The idea of parasitic inheritance is to create a function to encapsulate the inheritance process by passing in an object, then making a copy of the object, then extending the object, and finally returning the object. This process of extension can be understood as inheritance. The advantage of this inheritance is to implement inheritance on a simple object if the object is not of our custom type. The disadvantage is that there is no way to reuse the function.

function createObj (o) {
    var clone = Object.create(o);
    clone.sayName = function () {
        console.log('hi');
    }
    return clone;
}
Copy the code

(6) The sixth method is parasitic combinatorial inheritance. The disadvantage of combinatorial inheritance is that instances of supertypes are used as prototypes of subtypes, resulting in the addition of unnecessary prototype attributes. Parasitic composite inheritance uses a copy of the stereotype of the supertype as the stereotype of the subtype, thus avoiding the creation of unnecessary attributes.

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

console.log(child1)
Copy the code

Deep copy Shallow copy

Assignment Deep copy Shallow copy differentiates basic types, = assignment, copy reference type of value, = assignment, copy memory address

Copy:

  • Prepare a new object/array
  • Copy the old value to the new object/array

Shallow copy

  • What is shallow copy

Copy the value of the first item of the object/array into the new array/object. The second layer is also the copied pointer, referencing each other

  • Shallow copy application scenarios

Modify an array/object to affect another array/object, breaking their connection

  • How to implement shallow copy

    1, the Object. The assign ()

    2. Clone in Lodash

    3,… Expansion operator

    4, Array. Prototype. Concat

    5, Array. Prototype. Slice

Deep copy

  • What is deep copy

Copy the values of all layers of the object/array into the new object/array

  • How to implement deep copy

3. Determine the type of the object, create a new object, recursively call the function, continue to determine

Deep copy implementation

1, the JSON. Parse (JSON. Stringify ())

2. Recursive operations

CloneDeep in loadsh

Let oldObj = {name: 'xiaoming ', age: 18, grade: [100, 90], family: {fName: } function deepClone (newO, old) { for (let key in old) { let val = old[key] if (val instanceof Array) { newO[key] = [] deepClone(newO[key], val) } else if (val instanceof Object) { newO[key] = {} deepClone(newO[key], val) } else { newO[key] = val } } } deepClone(newObj, oldObj)Copy the code

Js throttling

Principle: If a method is triggered continuously, it will only trigger once at a specified time. Application Scenario: Page scrolling event Implementation: Timestamp, set timer HTML is the same as before

Timestamp mode

function throttle(fn, wait) { 
    let preTime = 0 
    return function () { 
        let nowTime = new Data() 
        let args = arguments; 
        let ctx = this 
        if (nowTime - preTime > wait) { 
            fn.apply(ctx, args) 
            preTime = nowTime 
        } 
    } 
}
Copy the code

Timer mode

function throttle(fn, wait) { let preTime = 0 let timeOut return function (params) { let ctx = this let args = arguments if (! timeOut) { timeOut = setTimeout(() => { fn.apply(ctx, args) timeOut = null }, wait)} } }Copy the code

If you learn

How it works: No matter how many times you call it, I only execute application scenarios once within a fixed time frame: button click events, screen scroll events, mouse scroll events, etc

function debounce(fn, wait) { 
    var timeOut 
    return function () { 
        let context = this 
        let args = arguments 
        clearTimeout(timeOut) 
        timeOut = setTimeout(function () { 
            fn.apply(context, args) 
        }, wait) 
    } 
}


Copy the code

EventLoop

When a script is executed for the first time, the JS engine parses the code, adds the synchronized code to the stack in the order it is executed, and then executes it from scratch. If a method is currently executing, js adds the method’s execution environment to the execution stack, and then enters the execution environment to continue executing the code. When the code in this execution environment completes and returns the result, js exits the execution environment and destroys the execution environment, returning to the execution environment of the previous method. This process is repeated until all the code in the execution stack has been executed,

Instead of waiting for an asynchronous event to return, the JS engine suspends the event and continues to execute other tasks in the stack. When an asynchronous event returns a result, JS adds the event to a different queue from the current stack, called the event queue. Instead of executing its callback immediately, it waits for all tasks in the current execution stack to complete, and when the main thread is idle, it looks up whether there are any tasks in the event queue. If so, the main thread will fetch the first event, place the corresponding callback on the stack, and execute the synchronization code. And so on and so on and so on and so on and so on and so on and so on and so on. This is why the process is called an Event Loop.

Macro Task vs. Micro Task

The above event loop is a macro statement, but because asynchronous tasks are different from one another, their execution priorities are different. Different asynchronous tasks are divided into two categories: micro tasks and macro tasks.

The following events are macro tasks:

  • setInterval()
  • setTimeout()

The following events are microtasks

  • new Promise()
  • new MutaionObserver()

As described earlier, in an event loop, asynchronous events return results that are placed in a task queue. However, depending on the type of asynchronous event, the event can actually be queued to the corresponding macro or microtask queue. And when the current stack is empty, the main thread checks for events in the microtask queue. If not, fetch an event from the macro task queue and add the corresponding event back to the current stack. If so, the queue will execute the corresponding callback until the microtask queue is empty, then fetch the first event from the macro task queue, and add the corresponding callback to the current stack. And so on and so on and so on.

We just need to remember that when the current stack finishes, all events in the microtask queue are processed immediately, and then an event is fetched from the macro task queue. Microtasks are always executed before macro tasks in the same event loop

Native ajax

Ajax is a method of asynchronous communication that retrieves data from the server and partially refreshes the page. Process:

  1. createXMLHttpRequestObject;
  2. callopenMethod passes in a three-parameter request method(GET/POST), URL, synchronous asynchrony (true/false);
  3. Listening to theonreadystatechangeEvents, whenreadystateReturns at 4responseText;
  4. The send method is called to pass the parameters.

Event bubbling, capture (delegate)

  • Event bubbling is when an event of some kind is fired on an object, if the object is bound to an event, then the event is fired, and if not, propagated to the object’s parent object, which eventually fires the event.
  • Event delegation essentially leverages the browser event bubbling mechanism. Since the event is uploaded to the parent node during the bubbling process, and the parent node can obtain the target node through the event object, the listener function of the child node can be defined on the parent node, and the listener function of the parent node can uniformly handle the events of multiple child elements, which is called event proxy.

Event.stoppropagation () or the ie method event.cancelBubble = true; // Prevent events from bubbling

Call aplly and bind

Both have the ability to change the context in which functions are executed, handing over methods from one object to another

Call writing

Function call (obj, [param1 [, param2 [paramN], [...]]])Copy the code

Note the following points:

  • The object that calls call must be a Function.
  • The first argument to call is an object. The caller of Function is going to point to this object. If not, the default is the global object Window.
  • Starting with the second parameter, any parameter can be accepted. Each parameter is mapped to the Function parameter at the corresponding location. But if you pass all the parameters as an array, they are mapped as a whole to the first parameter corresponding to Function, after which the parameters are empty.
Function func (a,b,c) {} func. Call (obj, 1,2,3) [1,2,3]) // func is actually [1,2,3],undefined,undefinedCopy the code

The apply of writing

Function.apply(obj[,argArray])
Copy the code

Note that:

  • Its caller must be Function, and it takes only two arguments, the first of which has the same rules as call.
  • The second argument, which must be an array or an array of classes, will be converted to an array of classes, passed into Function, and mapped to the corresponding parameters of Function. This is an important distinction between call and apply.
Func. Apply (obj, [1,2,3]) // func is actually [1,2,3] func.apply(obj, {0: 1, 1: 2, 2: 3, length: 3}) // the arguments received by func are actually 1,2,3Copy the code

An array of complementary classes is an object that has similar characteristics to an array and can be called with a corner pointer, with a length attribute, and can also be traversed through a for loop. However, it is important to note that an array of classes cannot use the methods on the array prototype chain such as forEach, Splice, and push. After all, it is not a real array

Use of Call Apply

1. Object inheritance

function superClass () { this.a = 1; this.print = function () { console.log(this.a); } } function subClass () { superClass.call(this); this.print(); } subClass(); / / 1Copy the code

If the class Array wants to use methods on the Array prototype chain, we can do this:

let domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Copy the code

The apply use

let min = Math.min.apply(null, array); Math.max, which is used to get the smallest item in the arrayCopy the code
let max = Math.max.apply(null, array); // Use it to get the largest item in the arrayCopy the code

Array.prototype.push is used to merge two arrays

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];

Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
Copy the code

The bind method

Function.bind(thisArg[, arg1[, arg2[, ...]]])
Copy the code

The bind method is similar to apply and call in that it can also change the “this” reference inside a function. The difference is that the bind method returns a function and needs to be called later before it is executed. Apply and call are immediate calls

function add (a, b) { return a + b; } function sub (a, b) { return a - b; } add.bind(sub, 5, 3); // 8 add.bind(sub, 5, 3)(); // After the call, return 8Copy the code

Promise

Basic process:

  1. Initialize the Promise state (pending)
  2. The fn function passed in the Promise is immediately executed, and the resolve and reject functions inside the Promise are passed to FN as parameters, which will be processed according to the event mechanism
  3. Perform then (..) Register callback processing arrays (then methods can be called multiple times by the same Promise)
  4. The key in the Promise is to ensure that the onFulfilled and onRejected parameters passed in by the THEN method must be executed in the new implementation stack after the event loop in which the THEN method is called.

A real chain Promise means that after the current Promise reaches the fulfilled state, the next Promise will be fulfilled.

Chain calls

This model is simple and easy to understand. The most crucial point here is the Promise newly created in THEN. The node whose state becomes a pity is when the callback of the previous Promise is fulfilled. That is, when the state of a Promise is fulfilled, its callback function will be executed, and the result returned by the callback function will be regarded as value and returned to the next Promise(that is, the Promise generated in then). The state of the next Promise is also changed (resolve or Reject), its callback is executed, and so on… That’s where the chain call effect comes in

Exception catch An exception is usually an error generated when the code fails to execute a success/failure callback. For this type of exception, try-catch is used and the Promise is set to rejected. It’s easy to run into a scenario where some final action has to be performed regardless of the final state of the Promise. We put these operations in finally, which means that finally registered functions are independent of the state of the Promise and do not depend on the result of the Promise’s execution. So we can write finally logic like ### # resolve and reject. In practice, we can use the Promise. Resolve and Promise. Used to wrap a non-Promise instance as a Promise instance. Here’s an example:

Resolve ({name:'winty'}) Promise. Reject ({name:'winty'}) New Promise((resolve,reject) => REJECT ({name:'winty'})) copy the codeCopy the code

In these cases, the Promise. Resolve entry can be one of the following:

  • No arguments [simply return a Resolved Promise object]
  • Plain data object [returns an Resolved Promise object directly]
  • An instance of Promise [returns the current instance directly]
  • A Thenable object (a Thenable object is an object with a THEN method) [becomes a Promise object and immediately executes the THenable object’s THEN method.]

The Promise. All parameter is an array of Promise instances, and then a THEN method is registered. After the state of the Promise instances in the array is changed to depressing, the THEN method will be implemented. This is mainly a counting logic. Every time a Promise state becomes a big pity, the data returned by the instance will be saved, and then the count will be reduced by one. When the counter becomes 0, All of the Promise instances in the delegate array have been executed. Promise.race now that promise.all is understood, promise.race is easier to understand. Its incoming parameters are also an array of Promise instances, and its then registered callback methods will be executed when the state of one of the promises in the array becomes progressively. Since the state of a Promise can only change once, all we need to do is inject the resolve method of the Promise object generated in promise.race into the callback function of each Promise instance in the array

conclusion

Promise source code is only a few hundred lines, we can start from the execution results, analyze the execution process of each step, and then think about its role. One of the key points is to understand that the THEN function is responsible for registering callbacks, and that the actual execution takes place after the state of the Promise has changed. When the input to resolve is a Promise, to chain the call, its then method (then.call) must be called, injecting the previous Promise’s resolve method into its callback array

ES6

  1. The new symbol type represents a unique value that defines a unique object property name.
  2. Const /let are used to declare variables that are non-repeatable and have block-level scope. There is a temporary dead zone, that is, there is no variable lift. (const is generally used to declare constants);
  3. Destruct assignment of variables (including arrays, objects, strings, numbers and bools, function parameters), residual operators (… rest);
  4. Template string (${data});
  5. Extension operators (arrays, objects);
  6. Arrow function;
  7. Set and Map data structures;
  8. Proxy/Reflect;
  9. Promise;
  10. Async functions;
  11. Class;
  12. Module syntax (import/export).

Four stages of precompilation

1. Create an AO object

2. Find the parameter and variable declaration, as the AO object property name, the value of undefined

3. Arguments and parameters are unified

If the function declaration is the same as the variable name, override the variable declaration (function promotion only promotes the function declaration, not the function expression).

This points to the problem

Definition: In JavaScript, the orientation of this is determined at call time, not creation time, which can make the orientation of this confusing. Simply put, this has run-time binding properties.

  • Global context
  • Function context
  • Call (), apply() this point to the bound object
  • Bind () this will be permanently bound to the first argument of bind
  • Arrow functions None of the arrow functions have their own this, pointing to the outer layer

Arrow function

  • This in the arrow function is bound when the function is defined, not when it is executed
  • In the arrow function, the point of this is fixed, not because the arrow function has a mechanism to bind this. The actual reason is that the arrow function does not have its own this, so the inner this is the this of the outer code block. Because it does not have this, it cannot be used as a constructor
  • This in the arrow function is bound when the function is defined
  • By definition time binding, this is inherited from the parent execution context

Js scope

Scope description: Generally understood as the scope of a variable

Global scope

  • The global scope is created when the function is opened and destroyed when the page is closed
  • Variables and functions compiled in script tags are global in scope and can be accessed anywhere on the page
  • There is a global object window in the global scope. Represents a browser window that is created by the browser and can be called directly
  • Variables and functions declared in the global scope are stored as property methods of the window object

Function scope

  • The function is called, the function scope is created, the function is executed, and the function scope is destroyed
  • Each call to a function creates a new function scope, which is independent of each other
  • A function scope can access variables in the global scope. Variables inside a function cannot be accessed from outside the function
  • If a variable is accessed from a function scope, it is searched inside the function first. If it is not found, it is searched in the function’s upper scope

Execution time context

  • At the beginning of function code execution, an execution context content object AO (scope) is created
  • This content object is created at precompilation time
  • An execution-time context object, GO, is created early in global code execution
  • For each execution context, there are three important properties:
1, Variable object (VO) 2, Scope chain (VO) 3, thisCopy the code

The scope chain

Definition: is the set of function scope AO and global scope VO

closure

function a() {
    var aa = 123
    function b() {
        console.log(aa)
    }
    return b
}
var res = a()
res()
Copy the code

When a function is destroyed, b function points to AO,VO link is not destroyed

Application: Singleton pattern

A point is globally accessible and can be cached

What is a closure

Closure is A special kind of object, it consists of two parts: the execution context (code A), was founded in the execution context and the function of the code (B), when B execution, if access to A variable in the the value of the object, the closure will produce, and in Chrome, using A function name generation refers to the execution context A closure.

How do you generate closures in general

  • Returns the function
  • Functions are passed as arguments

Application scenarios for closures

  • Currie bind
  • The module

Which operations cause memory leaks

  • closure
  • Unexpected global variables (undeclared directly assigned variables)
  • The forgotten timer
  • Reference out of the DOM (get the DOM, although the DOM is cleared after the code executes, the REFERENCE to the DOM remains in memory)

Higher-order functions

Definition: a function that takes a function as an argument or return value

event-loop

  • Language features: single threaded, interpreted language
  • The time loop mechanism consists of three parts: call stack, microtask queue and message queue
  • process

When the event-loop starts, it will be executed line by line globally. When the function is called, it will be pushed into the call stack. The pushed function is called frame, and when the function returns, it will pop from the call stack. For example, when the fetch setTimeOut setInterval is pressed into the call stack, the message inside will be entered into the message queue, and the content in the message queue will be executed after the call stack is emptied. 4. That is to say, the content in the microtask has a higher execution priority than the content in the message queue

var p = new Promise(resolve = > { console.log(4) resolve(5) }) function func1() { console.log(1) } function func2() { setTimeOut(() => { console.log(2) }, Func2 (resolve => {console.log(resolve)})} func2() 4, 1, 3, 5, 2Copy the code

Array flattening processing, multi-dimensional array into a one-dimensional array

Const arr = [1, 3, 2, [5], 7]]Copy the code

1. Use flat, call directly

Const result1 = arr.flat(infinity) const result1 = arr.flat(3) // [1,3,2,5,7] - flat() only flattens one layer by default, if you want to "flatten" multiple nested arrays, The argument to the flat() method can be written as an integer representing the number of layers you want to flatten, which defaults to 1. The flat() method returns a new array with no effect on the original array. The flat() method returns a new array with no effect on the original arrayCopy the code

2. Use re

const result2 = JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '').split(',') + ']')
Copy the code

3. Recursive processing

let result = []; let ary = [1, 2, [3, 4], [5, [6, 7]]] let fn = function(ary) { for(let i = 0; i < ary.length; i++) }{ let item = ary[i]; if (Array.isArray(ary[i])){ fn(item); } else { result.push(item); }}}Copy the code

4. Reduce implements the array Flat method

function flatten(ary) { return ary.reduce((pre, cur) => { return pre.concat(Array.isArray(cur) ? flatten(cur) : cur); })} let ary = [1, 2, [3, 4], [5, [6, 7]] flatten(ary) array.reduce(function(total, currentValue, The currentIndex, ARR), initialValue) -reduce () method takes a function as an accumulator, and each value in the array (from left to right) starts to shrink and eventually evaluates to a value. -reduce () can be used as a higher-order function for compose. Note: Reduce () does not perform a callback for an empty array.Copy the code

5. Expand operators

while (ary.some(Array.isArray)) { ary = [].concat(... ary); }Copy the code

BFC

Common positioning schemes

  • Normal flow
  • floating
  • Absolute positioning

The concept is that it is a rendering area of the page with a set of rendering rules. Elements with BFC properties can be viewed as separate containers, and the elements in the container have no effect on the layout of external elements

Trigger landing

  • Body root element
  • Float element: float a value other than None
  • Absolute position elements: Position (Absolute, fixed)
  • Display inline-block, table-cells, flex
  • Overflow values other than visible (hidden, auto, Scroll)

BFC features and applications 1. The margins of the same BFC can be folded (placed in different BFC) 2. The BFC can contain floating elements (clear floating) 3

inheritance

Prototype chain inheritance

How it works: When a subclass’s prototype object’s prototype attribute points to an instance of the parent class, the subclass will find its parent class along the prototype chain when the subclass’s object cannot find a method

function Parent () {
    this.name = 'kevin';
}

Parent.prototype.getName = function () {
    console.log(this.name);
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName()) // kevin
Copy the code

Disadvantages:

  • Multiple instances point to a stereotype, and if one instance modifies the stereotype, the others will also be modified
  • Unable to implement supre function, pass parameter to parent class

Constructors inherit advantages and disadvantages

Definition: In the constructor of a subclass, execute the constructor of the parent class and bind this to it

function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {
    Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]
Copy the code

Advantages:

  • Properties of reference types are prevented from being shared by all instances

  • You can pass an argument to a Parent in a Child

Disadvantages: Instances of subclass constructors cannot inherit method and attribute combinatorial inheritance from superclass stereotypes

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {

    Parent.call(this, name);
    
    this.age = age;

}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]
Copy the code

Advantages: Combining the advantages of stereotype chain inheritance and constructors is the most common inheritance pattern in JavaScript.

Disadvantages: no subclass instance is generated, the Parent constructor is called twice, and a new Parent instance is created once, new Child(), parent.call (this, name

Parasitic combinatorial inheritance

function Parent (name) { this.name = name; this.colors = ['red', 'blue', 'green']; } Parent.prototype.getName = function () { console.log(this.name) } function Child (name, age) { Parent.call(this, name); this.age = age; Var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); var child1 = new Child('kevin', '18'); console.log(child1);Copy the code

Finally, encapsulate the inheritance method:

function object(o) { function F() {} F.prototype = o; return new F(); } function prototype(child, parent) { var prototype = object(parent.prototype); prototype.constructor = child; child.prototype = prototype; } // prototype(Child, Parent);Copy the code

The Array includes

Defines the: includes() method to determine if an array contains a specified value, returning true if so, false otherwise.

Arr. Includes (searchElement) Arr. Includes (searchElement, fromIndex) - searchElement is mandatory. The value of the element to look up. - fromIndex Optional. The search starts at that index or, if negative, from the index of array.length + fromIndex in ascending order. The default is 0. [1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true [1, 2, NaN].includes(NaN); // trueCopy the code

Early exit, early return

Definition: Essentially parses the structures on both sides of the equal sign and assigns the corresponding values on the right to the left. If the deconstruction fails, the value of the variable is equal to undefined

Object destruct assignment without first declaring variables

Let {aa,bb} = {aa:123,bb:456}; Let {aa:aa,bb:bb} = {aa:123,bb:456}; console.log(aa,bb); / / 123 456Copy the code

Object key name and key value are inconsistent

Let {aa:a,bb:b} = {aa:123,bb:456}; let {aa:a,bb:b} = {aa:123,bb:456}; console.log(a,b); // 123 456 console.log(aa); // The aa is not definedCopy the code

Objects with default values destruct assignments

let {a = 3,b = 4} = {a:5} console.log(a,b); / / 5 4Copy the code
Application scenarios

Process the JSON data returned from the back end and extract the desired field values

let dataJson = { title:"abc", name:"winne", test:[{ title:"ggg", Let {title:oneTitle,test:[{title:twoTitle}]} = dataJson; let {title:oneTitle,test:[{title:twoTitle}]} = dataJson; Let {name} = dataJson; let {name} = dataJson; // let name = datajson.name; console.log(oneTitle,twoTitle); // abc ggg console.log(name); // winneCopy the code

Multi-layer judgment, saving code, convenient maintenance and modification

function animalsDet({type, name, gender} = {}) { if (! type) return if (! name) return if (! ${gender} '} animalsDet({type: 'dog', name: 'rich ', gender:' female '})Copy the code

Object self-facet instead of switch method

const fruitColor = {
    red: 'apple',
    yello: 'banner'
  }

  function printFruits(color) {
    return fruitColor[color] || []
  }

  console.log(printFruits('red')) // apple
Copy the code

Use the map

Note: The Map structure provides value-value mapping, which is a more complete Hash structure implementation. If you need key-value data structures, Map is better than Object. It is a collection of key-value pairs similar to objects, but the range of “keys” is not limited to strings. Values of all types (including objects) can be used as keys.

Definition:

let map = new Map(); let map = new Map([[key,value],[key,value]]); // Default initialization parameter definitionCopy the code

If the Map’s key is a value of a simple type (number, string, Boolean), as long as the two values are strictly equal, the Map treats it as a key, including 0 and -0. Also, although NaN is not strictly equal to itself, Map treats it as the same key

Instance properties and methods: size, set, get, has, delete, clear

Traversal methods: keys(), values(), entries(), forEach()

let item = {a: 1}; let set = new Set(); let map = new Map(); let obj = new Object(); / / add the set. The add (item); map.set('a', 1); obj['a'] = 1; / / check the set from the (item); // true map.has('a'); // true 'a' in obj; // true // change item.a = 2; map.set('a', 2); obj['a'] = 2; / / delete the set. The delete (item); map.delete('a'); delete obj['a']; console.log(set); console.log(map); console.log(obj);Copy the code

23, array-some and array-every

Test all fruits for red color

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yello' }
  ]

  function test() {
    const isAllRed = fruits.every(f => f.color === 'red')
    console.log(isAllRed) // false
  }

  test()
Copy the code
const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yello' }
  ]

  function test() {
    const isAllRed = fruits.some(f => f.color === 'red')
    console.log(isAllRed) // true
  }

  test()
Copy the code

Front-end cross-domain solutions

Homology means that the protocol, domain name, and port are the same. The same origin policy restricts the following behaviors:

  • Cookie, localStorage, and indexDB cannot be read
  • DOM and JS objects are not available
  • AJAX requests cannot be sent

1. JSONP is cross-domain

Jsonp uses

<script> var script = document.createElement('script'); script.type = 'text/javascript'; // Pass a callback function name to the back end, Convenient back-end returned to carry out the defined in front of the callback function script. The SRC = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback'; document.head.appendChild(script); Function handleCallback(res) {alert(json.stringify (res)); } </script>Copy the code

The server returns the following (executes the global function when it returns) :

handleCallback({"success": true, "user": "admin"})
Copy the code

2) jquery Ajax implementation

$. Ajax ({url: 'http://www.domain2.com:8080/login', type: "get", dataType: 'the json, / / requests for the json jsonpCallback: "HandleCallback ", // custom callback name data: {}});Copy the code
  1. Vue axios implementation
this.$http = axios;
this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})
Copy the code

2. Cross-domain Resource Sharing (CORS)

3, Nginx proxy cross domain

Nodejs middleware proxy is cross-domain

Document.domain + iframe cross domain

6. Location. hash + iframe cross-domain

7, window.name + iframe cross domain

PostMessage is cross-domain

9. WebSocket protocol is cross-domain

Browser cache

  • Each time the browser initiates a request, it first looks up the result of the request and the cache identifier in the browser cache
  • Each time the browser receives the result of the returned request, it stores the result and the cache id in the browser cache
Strong cache

Forced cache refers to the process of searching the browser cache for the request result and deciding whether to use the cached result based on the cache rule of the result. There are three cases of forced cache (the negotiation cache process is not analyzed for the moment), as follows

Strong cache rule

When the browser makes a request to the server, the server returns the Cache rule in the HTTP header of the HTTP response packet together with the request result to the browser. The fields that Control the mandatory Cache are Expires and cache-Control. Cache-control has a higher priority than Expires.

Cache-Control

In HTTP/1.1, cache-control is the most important rule, which is mainly used to Control web caching. Its main values are:

  • Public: All content will be cached (both client and proxy can be cached)
  • Private: All content can be cached only by the client. The default value of cache-control
  • No-cache: indicates the contents of the client cache, but whether to use the cache is verified by the negotiated cache
  • No-store: All content is not cached, that is, neither mandatory cache nor negotiated cache is used
  • Max-age = XXX (XXX is numeric) : The cache contents will expire after XXX seconds

Negotiate the cache

Negotiation cache is a process in which the browser sends a request to the server with the cache ID after the cache is invalid, and the server decides whether to use the cache based on the cache ID

conclusion

The mandatory-cache takes precedence over the negotiated Cache. If mandatory-cache (Expires and cache-control) is valid, the Cache is used directly, and If not, the negotiated Cache (last-modified/if-modified-since and Etag/if-none-match) is used. The server decides whether to use the negotiation cache. If the negotiation cache is invalid, the request cache is invalid, and the request result is obtained again and stored in the browser cache. If it takes effect, 304 is returned and the cache continues to be used. The main process is as follows:

HTML 5 new features

Header nav main article section aside footer

Semantic meaning as the name implies, semantic HTML5 refers to the reasonable and correct use of semantic tags to create page structures, such as header,footer and nav. The function of this tag can be intuitively known from the tag, rather than abusing div. The advantages of semantics are: the code structure is clear, easy to read, easy to develop and maintain and other devices (such as screen readers) to render web pages according to semantics. Good for search engine optimization (SEO), search engine crawlers copy code with different weights based on different tagsCopy the code

2. Local storage

H5 provides sessionStorage, localStorage, and indexedDB for enhanced localStorage. You should judge the support before using it

If (window.sessionStorage){// Browser support sessionStorage} if(window.localstorage){// browser support localStorage}Copy the code

LocalStorage differs from sessionStorage in that sessionStorage is session-based, and the storage disappears after closing the browser. LocalStorage has an upper limit of 2.6MB, which is much better than cookies. IndexedDB has an upper limit of 250MB. Another difference between localStorage and cookies is that there is no expiration time, but this can be easily solved by adding a time field to localStorage. Access to localStorage may encounter cross-domain problems, because localStorage is intra-domain security, that is, the same domain can be used to store localStorage, can be solved by postMessage. The following are common application scenarios

In addition, browsers provide storage events to listen for storage

 window.addEventListener('storage', showStorageEvent, true)
Copy the code

3. Offline Web applications

Page caching still refers to the network state, while offline Web applications refer to the application running without network state

If (window.applicationCache){// Support offline application}Copy the code

The manifest file is the core, which records which resource files need to be cached offline. To use the MANIFEST file, you just need to add attributes to the HTML tag

<html manifest="cache.manifest">
Copy the code

The cache. Manifest file format is as follows

NETWORK /images/ FALLBACK offline.html index.htmlCopy the code

When the NETWORK is not available, files are read directly from the local cache. Files under #NETWORK are downloaded from the NETWORK whether they are cached or not. After FALLBACK, if offline. HTML cannot be retrieved, go to index.html

4. New functions of forms

Instead of submitting the name and value in the input along with the form form, which had to wrap the input, you can now bind it with the Form property of the input

<form id="testform">
    <input type="text" />  
</form> 
<input form=testform />
Copy the code
  • Placeholder attribute
  • Autofocus attribute, page can only have one
  • Also, the type can be email, number, etc

5, CSS 3

CSS3 provides more selectors, before, after, first-child, and nth-Child. The effects provided include box-shadow, text-shadow, and background-size. For example, background-size syntax varies by browser, so use the following syntax

  • You can also use media-Query for a responsive layout

Transition animation

6. Geographic positioning

H5 provides the Geolocation API to access the geographical position, that is, through the window. The navigator. Geolocation visit to implement. This object has three methods:

getCurrentPosition()
    watchPosition()
    clearWatch
Copy the code

The first time a page uses the API, a user permission is required, and watchPosition listens for position changes.

7. Audio and video processing

Canvas/webGL

9, history apis

Web scoket IO

11, requestAnimationFrame

The difference between REM and EM, rem if not set

  1. Px is a fixed pixel that, once set, cannot be changed to fit the page size.
  2. Em and REM are more flexible than PX because they are units of relative length, meaning that the length is not fixed and is more suitable for responsive layouts.
  3. Em sets the font size relative to its parent element, usually with<body>“font-size”As the benchmark. The problem is that for any element setting, you might need to know the size of its parent element. And Rem is relative to the root element<html>, which means that we only need to determine a reference value at the root element.

Summary: The difference between EM and REM is summarized in one sentence: EM relative to parent element, REM relative to root element.

em

  • The child element font size em is relative to the parent element font size

  • Elements of width/height/padding/margin with em words is relative to the element of the font size

<div> Parent element div <p> child element p <span> grandson element span</span> </p> </div>Copy the code
div { font-size: 40px; < span style = "max-width: 100%; clear: both; /* 300px */ height: 7.5em; border: solid 2px black; } p {font-size: 0.5em; < span style = "max-width: 100%; clear: both; min-height: 1em; /* 150px */ height: 7.5em; border: solid 2px blue ; color: blue; } span {the font - size: 0.5 em; width: 7em; height: 6em; border: solid 1px red; display: block; color: red; }Copy the code

rem

Rem is all length relative to the root element, who is the root element? < HTML > element. The usual practice is to give HTML elements a font size, and then the length of other elements is rem

<div> Parent element div <p> child element p <span> grandson element span</span> </p> </div>Copy the code
html { font-size: 10px; } div { font-size: 4rem; /* 40px */ width: 20rem; /* 200px */ height: 20rem; border: solid 2px black; } p { font-size: 2rem; /* 20px */ width: 10rem; height: 10rem; border: solid 1px blue; color:blue ; } span {font-size: 1.5rem; width: 7rem; height: 6rem; border: solid 2px red; display: block; color: red; }Copy the code

Note that:

Reset sets the initial size of the HTML font to 50px in case js is disabled or not loaded or executed incorrectly.

The body font size should be set to 16px. This is so that the body font size does not inherit the parent HTML element’s 50px, but uses the default 16px

Px versus REM?

For those that only need to be adapted to a few mobile devices and the resolution has little impact on the page, use PX.

For the need to adapt to a variety of mobile devices, use REM, for example, only need to adapt to iPhone and iPad and other devices with relatively large resolution differences.

rpx

RPX is a unit of size for wechat applet to solve adaptive screen size. Wechat mini program specifies a screen width of 750rpx.

Whether on iPhone6 or other models, the screen width is 750rpx. Take iPhone6 for example, the screen width is 375px. After dividing it into 750rpx, 1rpx = 0.5px.

Wechat applet also supports REM size units. Rem specifies a screen width of 20rem, so 1rem = (750/20) RPX = 37.5rpx

Browser GC mechanism

Browser garbage collection mechanism: V8 memory size == 1.4GB (64-bit) 0.7GB (32-bit) the latest version of Node is 2GB. The semispace of the new generation is exactly equivalent To the semispace of the semispace. The size of the semispace of the new generation is 64M(64-bit). The semispace of the Old generation is divided into two parts: Old pointer space and Old data SPAC. They are continuous and the size is 1400M (64-bit)

Garbage recycling algorithms: 1. Copy is the Scavenge algorithm. Copy does not take time to replace space. The old generation is mark-compact. (1) Sweep first, and then those that are referenced by roots will be marked and not recycled. (2) Sweep, Mark, clean, and then Sweep will cover some of the garbage that will be recycled. When it comes time to recycle, you recycle less and faster

Marking method: full stop marking method —- “incremental marking method + three color marking method gray an entry node, his child node black, next time, the black gray, black white, and then repeat for the social need to sort out?? Because objects and arrays are stored in the heap, the heap is a continuous linear space that can’t fit into the gaps if you don’t tidy them up

How can the new generation promote the old generation? 1 copy that has undergone a garbage collection, 2 toSpac has occupied 25%

The understanding of the BOM

The window object

In plain English, all variables, objects, functions, etc. in a web page are ultimately child properties of the Window object

Global scope

In ECMAScript, the Window object acts like a Global object. That is, all variables declared in the Global scope and functions become properties and methods of the window, which can pass through the window. Property name (or method name) directly called

The following points need to be noted

  • usewindow.attrDeclared variables andvarDeclared variables have a difference, usevarDeclared variable, cannot be useddeleteDelete, usewindow.Declared variables can be deleted
  • In JavaScript, trying to use an undeclared variable throws an error, but passeswindowObject queries for undeclared variables and only returnsundefined
Navigate and open Windows

Window.open () can be used either to navigate to a specific URL or to open a new browser window

This function takes four arguments:

  • URL
  • Window target
  • A property string for a new window, for example:'height=400,width=400,top=10,left=10,resizable=yes'
  • Boolean value that replaces the current page (only valid if no new window is opened
// If there is a topFrame window, Is specified in the topFrame window open the url, or create a new window and named topFrame window. The open (' htttp://www.maxiaofei.com ', 'topFrame') = = > < a href="http://www.maxiaofei.com" target="topFrame"></a>Copy the code

Window.open () returns a reference to the new window, the window object of the new window

Var myWin = window.open('http://www.maxiaofei.com','myWin') copies the codeCopy the code

Window.close () is used only for Windows opened through window.open()

The newly created window object has a opener property that points to the original window object that opened it

Location object

Note: Window. location and document.location refer to the same object. Location is both a property of the Window object and a property of the Document object

Location The property of the object

In the url, for example: http://www.baidu.com:8080/web/javascript/test.js#12345?a=10&b=20

Gets the current browser page URL window.location

Modify the properties of the Location object

Every changelocation 的 hashFor any property other than that, the page will reload with the new URL

window.location = 'http://www.maxiaofei.com'

location.search = '?name=mafei&age=18'

location.hostname = 'www.baidu.com'

location.pathname = 'web/html/a.html'

location.port = '1234'

Copy the code

Any changes other than the hash value will generate a new record in the browser’s history, which can be navigated to the previous page using the browser’s back button. You can disable this behavior with the replace() method. Pages opened with replace cannot go back to the previous page

// Try typing the following code in the browser console. The browser will not support fallback location.replace('http://www.baidu.com')Copy the code
Reload the

throughlocation.reload()Method to reload the page

  • location.reload(): reload (possibly from cache)
  • location.reload(true): reload (reload from the server)

The navigator object

The client side identifies the browser standard, mainly used to record and check the browser and device main information, also can let the script register and query some of its own activities (plug-in)

The screen object

An object that simply stores the capabilities of the customer service. Contains the following attributes:

The history object

Since history is a property of the Window object, every browser window, every TAB, and even every frame has its own History object associated with a particular Window object

1, history.go()

  • Receives an integer number or string argument: Jumps to the page whose most recent record contains the specified string
History. go('maixaofei.com') // Search forward or backward for the specified string pageCopy the code
  • When the parameter is an integer, a positive number indicates that the page is forwarded, and a negative number indicates that the page is forwarded
History. go(3) // Jump forward three records history.go(-1) // jump forward one recordCopy the code

2, the history. The forward ()

  • Jump forward one page

3, the history. The back ()

  • Jump backwards to a page

4, the history. Length

  • Gets the number of history records, if it is the first page openedhistory.length == 0, you can use this property to determine whether the currently opened web page is the first web page opened by the window

conclusion

This article mainly introduces several common objects in the browser Object Model (BOM), including Navigator, Window, Location, history

  1. windowIt’s both a JavaScript global object and an instance of the BOM, and all of the global methods, properties, properties in the BOM, can pass throughwindow.To invoke the
  2. windowAs examples of BOM, the most common methods are:window.open().window.close()To open and close a browser window, use the close method to open a page
  3. The location object is also one of the more commonly used BOM objects. It is used to manipulate URL-related information. Any property other than the Hash is reloaded and a history is added to the history
  4. locationThere’s another objectreload()Method to manually reload the page, which accepts an optional argument, istrueReload from the server, otherwise the page might be reloaded from the browser cache
  5. Location objectAnd then there’s a special way,location.replace(), which overwrites and reloads the current page without generating a history in History
  6. The Navigator object is mainly used to obtain browser-related information, so you should pay attention to compatibility when using it. Can be used to retrieve the browser (Chrome, safrai, FireFox, Edge, IE) and so on
  7. The history objectIt is used to manipulate the history of the browser URL. You can use parameters to move forward, backward, or to a specified URL. Can be achieved bylengthProperty gets the number of records to determine whether the current page is the first page opened

Difference between SRC and href in HTML

SRC is used to replace the current element, and href is used to establish a link between the current document and the referenced resource

src

SRC, short for source, refers to the location of an external resource, which will be embedded in the document at the current tag location. SRC resources are downloaded and applied to documents when requested, such as JAVASCRIPT scripts, IMG images, and frame elements

When the browser parses the element, it suspends the downloading and processing of other resources until the resource is loaded, compiled, and executed, as do elements such as images and frames, similar to embedding the pointed resource in the current tag. Is that why you put js scripts at the bottom and not at the head

href

Href is short for Hypertext Reference. It refers to the location of a web resource and establishes a link between the current element (anchor) or document (link)

<link href="common.css" rel="stylesheet"/>
Copy the code

The browser recognizes the document as a CSS file, downloads the resource in parallel, and does not stop processing the current document. Is this why it is recommended to load CSS using link rather than @import

Browser rendering mechanics, redrawing, rearrangement

Web page generation process:

  • HTMLTo be parsed by an HTML parserDOM
  • cssIs parsed by the CSS parserCSSOM The tree
  • In combination withDOMTrees andCSSOMTree to generate a render tree (Render Tree)
  • Generate layout (flow), that is, all nodes of all render trees are planar composited
  • Draw the layout (paint) On the screen

Rearrangement (also known as backflow): When a DOM change affects the element’s geometry (the position and size of the DOM object), the browser needs to recalculate the element’s geometry and place it in the correct position in the interface, a process called rearrangement. Trigger:

  1. Add or remove visible DOM elements
  2. Element size changes — margins, padding, borders, width, and height

Repainting: The process of redrawing an element when its appearance is changed without changing its layout. Trigger:

  • element-alteringColor, background, box-shadowAttributes such as

Rearrangement optimization suggestions:

  1. Separate read/write operation
  2. Style set modification
  3. The cache needs to be modifiedDOMThe element
  4. Try to only modifyPosition: absoluteorfixedElement has little effect on other elements
  5. Animation startGPUSpeed up,translateuse3Dchange

The transform does not redraw because the transform is a composite property. When you animate a composite property, a composite layer is created. This allows animation elements to be rendered in a separate layer. When the content of the element has not changed, there is no need to redraw it. The browser creates the animation frame by recomposing it.

CSS

The CSS is horizontally and vertically centered

This kind of problem is very common in projects, and I will briefly mention a few, but certainly not limited to them

Transform: translate(-50%,-50%); Add position: relative to parent of current div

`div{` ` ``background:red; ` ` ``position: absolute; ` ` ``left:50%; ` ` ``top:50%; ` ` ``transform: translate(-50%, -50%); ` ` `}Copy the code

2, absolute positioning method: determine the width of the current div, margin value is a negative half of the width of the current div

`div{` ` ``width:600px; ` ` ``height: 600px; ` ` ``background:red; ` ` ``position: absolute; ` ` ``left:50%; ` ` ``top:50%; ` ` ``margin-left:-300px; ` ` ``margin-top:-300px; ` ` `}Copy the code

3, absolute positioning method: under absolute positioning, set top left right bottom to 0

`div.child{` ` ``width: 600px; ` ` ``height: 600px; ` ` ``background: red; ` ` ``position:absolute; ` ` ``left:0; ` ` ``top: 0; ` ` ``bottom: 0; ` ` ``right: 0; ` ` ``margin: auto; ` ` `}Copy the code

Flex layout

`.box{` ` ``height:800px; ` ` ``-webkit-display:flex; ` ` ``display:flex; ` ` ``-webkit-align-items:center; ` ` ``align-items:center; ` ` ``-webkit-justify-content:center; ` ` ``justify-content:center; ` ` ``border:1px solid #ccc; ` `}` `div.child{` ` ``width:600px; ` ` ``height:600px; ` ` ``background-color:red; ` ` `}Copy the code

The display attribute of the child element can be set to inline or inline-block. Then the parent element must have a fixed width and height to achieve horizontal and vertical center. The table-cell middle center is used in combination

`display: table-cell; ` ` ``vertical-align: middle; ` ` ``text-align: center; ` ` ``width: 240px; ` ` ``height: 180px; ` ` ``border:1px solid #666; `Copy the code

6, absolute positioning: calc() function dynamic calculation to achieve horizontal and vertical center

`.calc{` ` ``position: relative; <``br``> border: 1px solid #ccc; <``br``> width: 400px; <``br``> height: 160px; ` `}` `.calc .child{` ` ``position: absolute; <``br``> width: 200px; <``br``> height: 50px; ` ` ``left:-webkit-calc((400px - 200px)/2); ` ` ``top:-webkit-calc((160px - 50px)/2); ` ` ``left:-moz-calc((400px - 200px)/2); ` ` ``top:-moz-calc((160px - 50px)/2); ` ` ``left:calc((400px - 200px)/2); ` ` ``top:calc((160px - 50px)/2); ` ` `}Copy the code

CSS box model

All HTML elements can be thought of as boxes, and in CSS, the term “box model” is used for design and layout. The CSS box model is essentially a box that encapsulates the surrounding HTML elements, including: margins, borders, padding, and actual content. The box model allows us to place elements in the space between other elements and the borders of surrounding elements.

IE model element width = Content + padding + border Height calculation is the same

Standard model element width = content contains only the content part, not the padding height calculation is the same

CSS styles

Implement a triangle

  border: 10px solid #000;
  border-left-color: #f00;
  width: 0;
  height: 0;
Copy the code

Make a trapezoid

  border: 10px solid #000;
  border-left-color: #f00;
  width: 10px;
  height: 10px;
Copy the code

Implement a triangulated wireframe

  height: 10px;
  width: 10px;
  border-left: 1px solid #cc0000;
  border-top: 1px solid #cc0000;
  transform: rotate(135deg);
Copy the code

Realization of animation

@keyframes example { from {background-color: red; } to {background-color: yellow; }} /* Apply an animation to this element */ div {width: 100px; height: 100px; background-color: red; animation-name: example; animation-duration: 4s; }Copy the code

Combinator selector

In CSS, combinators allow you to group multiple selectors together, which allows you to select elements within, or adjacent to, other elements. The four types available are:

  • Descendant selectors — (space) — allow you to select an element nested within another element (not necessarily direct descendants; For example, it could be a grandchild).
  • Child selectors — > — allow you to select an element that is a direct child of another element.
  • The neighboring sibling selector — + — allows you to select an element that is a direct sibling of another element (that is, next to it, at the same level of the hierarchy).
  • The universal sibling selector — ~ — allows you to select siblings of other elements (for example, at the same level in the hierarchy, but not necessarily right next to it)

Style priority

! important>style>id>class

What is BFC? What are the layout rules of the BFC? How do I create a BFC? Landing the application?

BFC stands for Block Formatting Context, which is a rendering area on a page and has a set of rendering rules that determine how its children will be positioned, Elements with BFC properties can be viewed as separate containers, the elements inside the container do not affect the layout of the elements outside, and BFC has some properties that normal containers do not have

Layout rules: Boxes are the object and basic unit of CSS layout. A page is composed of several boxes. The element type and display attribute determine the type of the Box. Different types of boxes participate in different Formatting contexts.

Create the landing:

  • Body root element
  • Float element: float a value other than None
  • Absolute position elements: Position (Absolute, fixed)
  • Display inline-block, table-cells, flex
  • Overflow values other than visible (hidden, auto, Scroll)

Features and Applications:

  • Margins fold under the same BFC – if you want to avoid overlapping margins, put them in different BFC containers
  • The BFC can contain floating elements (clear floating) – floating elements are removed from the document flow, and if the CONTAINER’s BFC is triggered, the container will be wrapped around floating elements
  • BFC prevents elements from being overwritten by floating elements – implementing multi-column layouts

DOM and BOM objects

The Browser Object Model (BOM) refers to the Browser Object Model. You can access and operate the Browser window. Using the BOM, developers can move Windows, change text in the status bar, and perform other actions that are not directly related to the content of the page. Enable JavaScript to “talk” to the browser. DOM (Document Object Model) refers to the Document Object Model, through which you can access all the elements of an HTML Document. DOM is a W3C (World Wide Web Consortium) standard. The DOM defines the standard for accessing HTML and XML documents: “The W3C Document Object Model (DOM) is a platform – and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of documents.” The W3C DOM standard is divided into three distinct parts:

  • The coreDOM– Standard model for any structured document
  • XML DOM– Standard model for XML documents
  • HTML DOM– Standard model for HTML documents

What is the XML DOM? The XML DOM defines the objects and attributes of all XML elements, as well as the methods to access them. What is the HTML DOM? The HTML DOM defines the objects and attributes of all HTML elements, as well as the methods to access them.

A small note

  1. Class array objects are converted to array objects
  • Array.prototype.slice.call(arguments)
  • . Expansion operator
  • Arrow functions have no arguments objects

2. Why does b in code become a global object when a function is called

Function fun() {let a=b=0} function fun() {let a=b=0Copy the code

3. The default object attribute is key:value. If the key is not a string, the toString method is implicitly called to convert the key to a string