This article has more than 66,000 Markdown words and 55,000 HTML words. Writing an article is not easy, it is suggested to collect, like, comment three.

What is a compiled language? What is interpreted language?JSWhat kind of language is it?

Compiled languages

1. Explain

Programs need a special compilation process before execution. The program is compiled into a machine-language file, which is used directly at run time without retranslation.

2. The advantages and disadvantages of

Program execution efficiency, compiler – dependent, less cross-platform.

3. For example

C and C++ are compiled languages.

Interpretive language

1. Explain

The program does not need to be compiled; it is translated into machine language at runtime, every time it executes.

2. The advantages and disadvantages of

Interpreted languages are less efficient and cannot run without an interpreter, but they can be easily cross-platform by providing a specific interpreter.

3. For example

Python and JS are interpreted languages.

Casting & Implicit casting

1.JSWhat are cast and implicit casts in?

1. Cast type

  • String()
  • Number()
  • Boolean()
  • parseInt()
  • parseFloat()

2. Implicit type conversion

  • + stringConverted to digital
  • a + " "Convert to string
  • ! varConvert to a Boolean value

Basic and reference data types

1, the difference between

1. As an argument to a function:

  1. Basic data types are passed in a copy of the data, and changes to the original data do not affect the incoming data.
  2. A reference data type is passed in the reference address of the data, and changes to the original data affect the incoming data.

2. Storage location in memory:

  1. Basic data types are stored in stacks.
  2. A reference data type stores a pointer in the stack to which the data entity is stored in the heap.

2. Stack and heap allocation in memory

eg:var a = {name: 'yuhua'}Variable storage

  1. Put this code inCode Segment;
  2. The variableaIn theStack: local variables, Pointers;
  3. will{name: 'yuhua'}In theHeapTotal: Object, closure.

3,symbol

1. symbolHow to obtain the key name of an object?

Can’t getsymbolKey:

  1. for infor ofIn the loop, it does not getsymbolKey;
  2. Object.keys(),Object.getOwnPropertyNames(),JSON.stringify()Method not availablesymbolKey;

Can getsymbolKey:

  1. Object.getOwnPropertySymbols()Method can get, return an array;
  2. Reflect.ownKeys()All key names can be obtained, includingsymbol

2. symbolType conversion of

1) Can be converted tostring
const symbolKey = Symbol(123)
String(symbolKey) // "Symbol(123)"
symbolKey.toString() // "Symbol(123)"
Copy the code
2) Can be converted to a Boolean value
Boolean(symbolKey) // true
Copy the code
3) Cannot be converted to numbers (error)
Number(symbolKey)
Uncaught TypeError: Cannot convert a Symbol value to a number
    at Number (<anonymous>)
    at <anonymous>:1:1
Copy the code
4) Convert to objects
b = Object(symbolKey)
Symbol {Symbol(123)}
  description: "123"
  __proto__: Symbol
    constructor: ƒ Symbol(a)description: "123"
    toString: ƒ toString ()valueOf: ƒ the valueOf ()Symbol(Symbol. ToPrimitive) : ƒ [Symbol.toPrimitive]()
    Symbol(Symbol.toStringTag): "Symbol"Get the description: ƒ description ()__proto__: Object
    [[PrimitiveValue]]: Symbol(123)
typeof b // "object"
b.constructor() // Symbol()
b instanceof Symbol // true
b instanceof Object // true
Object.prototype.toString.call(b) // "[object Symbol]"
Copy the code

4. String to function

1. eval()

let funcStr = "function test(value){alert(value)}";
let test = eval("(false || "+funcStr+")");
test("The function can execute.");
Copy the code

2. new Function()

function add(a, b) {
  return a + b;
}
/ / equivalent to the
var add = new Function ('a'.'b'.'return a + b');
let funcStr = "function test(value){alert(value)}";
let funcTest = new Function('return '+funcStr);
funcTest()("Functions can also execute.")
Copy the code

Four,nullundefinedThe difference between

1.Null

  • nullRepresents a “none” object, converted to a value of0;
  • As arguments to a function, indicating that the function’s arguments are not objects;
  • As the end of the object prototype chain.
  • Number(null)0
  • 5 + null5

2,Undefined

  • The variable is declared, but not assigned, is equal toundefined;
  • When the function was called, the argument that should have been provided was not providedundefined;
  • The object has no assignment property, which has a value ofundefined;
  • The function returns no value by defaultundefined;
  • Number(undefined)NaN;
  • 5 + undefinedNaN.

Five,typeofinstanceofThe difference between

1. Main differences

  • typeofRepresents a test for a variable type other than the basic data typenullAll types are normally displayed as the corresponding type, and reference types except functions are displayed asfunctionAll others will be displayed asobject;
  • instanceofThe prototype object used to check if a constructor is on an object’s prototype chain.

2,typeofnullError display of

This is just a long-standing Bug with JS. In the original version of JS, the 32-bit system was used. For the sake of performance, the type information of the variable was stored at the low level. The beginning of 000 represents an object, while null represents all zeros, so it was wrongly judged as object.

3. Implement oneinstanceof

Object.getprototypeof () : The object.getProtoTypeof () method returns the Prototype of the specified Object (the value of the internal [[Prototype]] property).

function myInstance (left, right) {
	let proto = Object.getPrototypeOf(left) The object.getProtoTypeof () method returns the Prototype of the specified Object (the value of the internal [[Prototype]] property).
  	while(true) {
  		if (proto === null) return false
	    if (proto === right.prototype) return true
    	proto = Object.getPrototypeOf(proto)
  	}
}
Copy the code

validation

myInstance([], Object) //true
myInstance(Map.Object) //true
myInstance(new Map(), Object) //true
myInstance(Map.Function) //true
myInstance(class {}, Function) //true
myInstance(1.Number) //true
myInstance('1'.String) //true
Copy the code

Vi.this

1. Describe itthis

For a function, the object that points to the last called function is an internal object automatically generated when the function is running and can only be used inside the function. For the global, this refers to the window.

2. Inside the functionthisWhen was it decided?

When a function is called, it points to the object that was last called

3,call,apply,bindThe difference between the three

All three functions bind the function to its context and change the reference to this in the function. The difference between the three is in grammar.

fun.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg, [argsArray])
var bindFn = fun.bind(thisArg[, arg1[, arg2[, ...]]])
bindFn()
Copy the code

The difference between Apply and call is that the call method accepts a list of arguments, while Apply accepts an array of arguments. The bind() method, on the other hand, creates a new function that, when called, sets its this keyword to the supplied value and, when called, provides a given sequence of arguments before any supply.

const name = 'window'
const sayName = function (param) {
    console.log('my name is:' + this.name + ',my param is ' + param)
}
sayName('window param') //my name is:window,my param is window param

const callObj = {
    name: 'call'
}
sayName.call(callObj, 'call param') //my name is:call,my param is call param

const applyObj = {
    name: 'apply'
}
sayName.apply(applyObj, ['apply param']) //my name is:apply,my param is apply param

const bindObj = {
    name: 'bind'
}
const bindFn = sayName.bind(bindObj, 'bind param')
bindFn() //my name is:bind,my param is bind param
Copy the code

4. What kinds of directions does this refer to?

  1. Default binding: in the global environment,thisDefault binding towindow.
  2. Implicit binding: Generally, when called by a function contained in a direct object, also known as a method call,thisImplicitly bound to the direct object.
  3. Implicit loss: Implicit loss is when the function that is implicitly bound loses the bound object, thus defaulting towindow. Explicit binding: Passcall(),apply(),bind()Method binds an object tothisThis is called explicit binding.
  4. newBinding: If a function or method call is preceded by a keywordnew, which constitutes the constructor call. forthisFor bindings, it is callednewBinding.

5, arrow functionthis

  1. Arrow function doesn’t have anythis, so you need to find out by looking at the scope chainthisWhich means that if an arrow function is contained by a non-arrow function,thisBind to the nearest layer of non-arrow functionsthis.
  2. Arrow functions don’t have their ownargumentsObject, but can access the peripheral functionargumentsObject.
  3. Can’t passnewThe same goes for keyword callsnew.targetValues and prototypes.

6. Manual implementationcall,applybind?

1. call

Function.prototype.myCall = function (thisArg, ... args) {
    const fn = Symbol('fn') // Declare a unique symbol property to prevent fn from overwriting existing properties
  	thisArg = thisArg || window // If no this is passed, the window object is bound
  	thisArg[fn] = this // This refers to the call object, that is, we want to change the function this refers to
  	constresult = thisArg[fn](... args)// Execute the current function
  	delete thisArg[fn] // Delete the fn we declared
  	return result // Returns the result of the function execution
}
Copy the code

2. apply

Function.prototype.myApply = function (thisArg, args) {
    const fn = Symbol('fn') // Declare a symbol
  	thisArg = thisArg || window / / set thisArg
  	thisArg[fn] = this // This points to change
  	constresult = thisArg[fn](... args)// Execute the function
  	delete thisArg[fn] / / delete the fn
 	return result // Return the result
}
Copy the code

3. bind

Function.prototype.myBind = function (thisArg, ... args) {
    const self = this
  	const fbound = function () {
    	self.apply(this instanceof self ? this : thisArg,args.concat(Array.prototype.slice.call(arguments)))
  	}
  	fbound.prototype = Object.create(self.prototype)
  	return fbound
}
Copy the code

7, judgment,thisPoint to the

1. obj0.obj.test()

const a = 1
function test () {
    console.log(this.a)
}
const obj = {
    a: 2,
    test
}
const obj0 = {
    a: 3,
    obj 
}
obj0.obj.test() / / 2
Copy the code

2. testcopy()

var a = 1
function test () {
    console.log(this.a)
}
const obj = {
    a: 2,
    test
}
const testCopy = obj.test
testCopy() / / 1
// The this reference is determined at function execution time
Copy the code

In 3.setTimeout

var a = 1
function test () {
    console.log(this.a)
}
const obj = {
    a: 2,
    test
}
setTimeout(obj.test) / / 1
// The this reference is determined at function execution time
Copy the code

Seven,JSmodular

1. Modular development history

  • IIFESelf-executing function
  • AMDuserequireJSTo write modularity (dependencies must be declared in advance.)
  • CMDuseseaJSTo write modularity (support dynamic introduction of dependent files.)
  • CommonJS nodeJsBuilt-in modularity in
  • UMDCompatible withAMD,CommonJSgrammar
  • webpack(require.ensure):webpack 2.xCode splitting in version
  • ES Modules:ES6Introduction of modularity supportimportLet’s introduce another onejs
  • scriptThe labeltype="module"

2,AMDCMDThe difference between

The biggest difference between AMD and CMD is that the execution time of the dependent module is different. Note that it is not the loading time or the way is different. Both are asynchronous loading modules

  • AMDDependency preloading is preferred. When defining a module, you should declare the module that it depends on
  • CMDUse proximity only when you need a modulerequire

3,CommonJSSpecification characteristics

  1. So the code runs in the module scope and does not pollute the global scope
  2. Modules are loaded synchronously, and subsequent operations will not be performed until the imported modules are loaded
  3. Modules are cached after the first execution, and reloading only returns cached results
  4. CommonJSThe output is a copy of the value, and changes within the module do not affect the value (reference type and base type are different).

4,ES6 modulesWhat are the characteristics of the specification

  1. The output usingexport
  2. Introduction to useimport
  3. You can useexport ... from ...To achieve a transit effect
  4. Input module variables are not reassigned. It’s just a readable reference, but you can overwrite properties
  5. exportimportCommands are at the top of the module, can’t be scoped, in a code block, can’t do static optimization, brokenES6The design intention of the module
  6. importThere is a promotion effect, will be promoted to the head of the entire module, execute first
  7. Babeltheexport/importintoexports/requireForm, so can be usedexportsimport

5,CommonJSES6 ModulesSpecification distinction

  1. CommonJSModules are loaded at runtime,ES6ModulesIt is loaded at compile time
  2. CommonJSA copy of the output value,ES6ModulesReferences to output values (changes within the module affect references)
  3. CommonJSAn import module can be an expression (which is usedrequire()The introduction of),ES6ModulesImports can only be strings
  4. CommonJSWhere this refers to the current module,ES6ModulesthisPoint to theundefined
  5. ES6ModulesThere is noarguments,require,module,exports,__filename,__dirnameThese top variables

6. How to load modules asynchronously

AMD and CMD support asynchronous loading of modules

7. What issues should be considered when developing a module?

  1. security
  2. closed
  3. Avoiding variable conflicts
  4. Isolation scope
  5. The pull-out of common code

Eight,node require(X)What is the processing order introduced?

  1. ifXIs a built-in module, returns the module, and does not continue execution;
  2. ifX'./', '/', '.. / 'The beginning will be based onXParent module, okXThe absolute path to: aXAs a file, search in sequence, exist, return the file, do not continue to execute; B. willXIf the file exists, the system returns the file and does not continue the execution.
  3. ifXWithout a path: a. According toXParent module, okXPossible installation directories b. In each directory in turn, willXLoad as filename or directory name
  4. thrownot founderror

9. Node references each other

There are two files a.js and B.js, which refer to each other

1. CommonJS

{
  id: '... '.exports: {... },loaded: true.parent: null.filename: ' '.children: [].paths: []}Copy the code

CommonJS module is a script file. The first time the script is loaded, the require command executes the entire script and then generates an object in memory. The module will be exported to the exports property when needed. Even if the require command is executed again, the module is not executed again, but is evaluated in the cache.

An important feature of CommonJS is that it is executed at load time, and all script code is executed at require.

The CommonJS approach is that once a module is “loop-loaded”, only the parts that have been executed are printed, and the parts that have not been executed are not.

// a.js
exports.done = false;
var b = require('./b.js');
console.log('in a.js, b.tone = %j', b.done);
exports.done = true;
console.log('A.js completed');
//b.js
exports.done = false;
var a = require('./a.js');
console.log('在 b.js 之中,a.done = %j', a.done);
exports.done = true;
console.log('B.js completed');
Copy the code
  1. a.jsThe script starts by printing onedoneVariable, and then load another script fileb.js. Notice that at this pointa.jsThe code just sits there and waitsb.jsAfter the command is executed, proceed to the next step.
  2. b.jsThe second line is loadeda.jsAt this point, “cyclic loading” occurs. The system will go toa.jsOf the module corresponding to the objectexportsProperty value, but becausea.jsIt’s not done yet, fromexportsProperty can only fetch what has already been executed, not the last value.
  3. a.jsThe part that has been executed is only one line.
exports.done = false;
Copy the code
  1. Therefore, forb.jsIn terms of it froma.jsEnter only one variabledoneAnd has a value offalse.
  2. b.jsAnd then it goes down, and when it’s all done, it gives it backa.js. As a result,a.jsThen proceed until the execution is complete. Let’s write a scriptmain.jsAnd run to verify the process.
// main.js
var a = require('./a.js');
var b = require('./b.js');
console.log('在 main.js 之中, a.done=%j, b.done=%j', a.done, b.done);
/ / run
// in b.js, a.tone = false
// b.js The execution is complete
// in a.js, b.tone = true
// a.js The execution is complete
// 在 main.js 之中, a.done=true, b.done=true
Copy the code
  1. The code above proves two things. One is inb.js,a.jsOnly the first line is executed. The second is,main.jsThe second line is not executed againb.jsIt is output cachedb.jsThe execution result of, its fourth line.

2. ES6

The ES6 module operates differently from CommonJS in that when it encounters the module load command import, it does not execute the module, but only generates a reference. Wait until you really need to use it, and then go to the module to value.

ES6 module is dynamic reference, there is no cache value problem, and the variables in the module, bound to its module. ES6 modules do not cache run results, but dynamically remove loaded module values, and variables are always bound to the module in which they reside.

ES6 doesn’t care if “loop-loading” occurs or not, it just generates a reference to the loaded module, requiring the developer to ensure that the value is retrieved when it is actually evaluated.

// even.js
import { odd } from './odd'
export var counter = 0;
export function even(n) {
  counter++;
  return n == 0 || odd(n - 1);
}
// odd.js
import { even } from './even';
export function odd(n) {
  returnn ! =0 && even(n - 1);
}
Copy the code

According to the CommonJS specification, it will not load, will report an error, but ES6 can be executed. This is possible because ES6 loads variables that dynamically reference their modules. As long as the reference exists, the code executes.

$ babel-node
> import * as m from './even.js';
> m.even(10);
true
> m.counter
6
> m.even(20)
true
> m.counter
17
Copy the code

In the code above, foo() is executed six times as n goes from 10 to 0, so the variable counter is equal to 6. On the second call to even(), the argument n changes from 20 to 0, foo() is executed 11 times, plus the previous six, so the variable counter is equal to 17.

Eight,JSThe event

1. What is event delegation

Event delegate/event proxy: Typically, an element’s event-responding function is delegated to its parent or outer element via event bubbling.

Disadvantages:

  1. Can only support bubbling events, for non-bubbling events cannot be proxy (focus/blur )
  2. All events are prone to error proxy, it is recommended to delegate nearby
  3. Internal elements have too many levels and are easily blocked by a layer

2,document,window,html,bodyHierarchical relationship of

window > document > html > body

  • windowBOMThe core object used to get or set browser properties and behavior, and as a global object.
  • documentIs a document-related object with functions to manipulate document content;
  • htmlElements anddocumentThe element object belongs tohtmlThe documentDOMObject.

3,addEventListenerWhat is the third argument to the function?

1. When tobooleanWhen:

  • The third parameter concerns whether to bubble or capture;
    • fortrueIs capture, and isfalseIs bubbling.

2. When toObjectWhen:

  • capture:BooleanSaid,listenerPropagated to this during the event capture phase of this typeEventTargetWhen triggered.
  • once:BooleanSaid,listenerIt is called at most once after addition. If it istrue.listenerIt is automatically removed after it is called.
  • passive:Boolean, is set totrueSaid,listenerNever callpreventDefault(). iflistenerIf this function is still called, the client will ignore it and throw a console warning.
  • mozSystemGroup: only inXBLOr is itFirefox' chromeUse, this is aBooleanSaid,listenerIs added to thesystem group.

4. The specific process of bubbling and capturing

Bubble: When an event is bound to an element, the event is triggered in turn in its parent element. Capture: Pass from top to bottom, as opposed to bubbling.

<! Button li ul -->
<ul onclick="alert('ul')">
  <li onclick="alert('li')">
    <button onclick="alert('button')">Click on the</button>
  </li>
</ul>
<script>
  window.addEventListener('click'.function (e) {
    alert('window')})document.addEventListener('click'.function (e) {
    alert('document')})</script>
Copy the code

Button -> ul -> document -> document -> li -> button

5. What are the non-bubbling events

  • onblur
  • onfoucs
  • onmouseenter
  • onmouseleave

6. Native custom events

1. Custom events

  • useEvent
  • usecustomEvent
  • usedocument.createEvent('customEventName')initEvent()

2. Create a custom event

1) useEvent
let myEvent = new Event('my_event_name')
Copy the code
2) usecustomEvent
let myEvent = new CustomEvent('my_event_name', {
    detail: {
    // Parameters to pass
    // Get: event.detail in the listener callback}})Copy the code
3) usedocument.createEvent('CustomEvent')initEvent()
let myEvent = document.createEvent('CustomEvent')
myEvent.initEvent(
    // event_name is the event name
  // Whether canBubble bubbles
  // cancelable Specifies whether the default behavior can be cancelled
)
Copy the code

3. Event monitoring

dom.addEventListener('my_custom_name'.function(e) {})
Copy the code

4. Event triggering

dispatchEvent(myEvent)
Copy the code

Case 5.

/ / 1.
let myEvent = new Event('myEvent');
/ / 2.
let myEvent = new CustomEvent('myEvent', {
  detail: {
    name: 'lindaidai'}})/ / 3.
let myEvent = document.createEvent('CustomEvent');
myEvent.initEvent('myEvent'.true.true)
let btn = document.getElementsByTagName('button') [0]
btn.addEventListener('myEvent'.function (e) {
  console.log(e)
  console.log(e.detail)
})
setTimeout(() = > {
  btn.dispatchEvent(myEvent)
}, 2000)
Copy the code

Nine,JSInner functions and closures

What is a closure

MDN: A combination of a function bound (or surrounded by) references to its surrounding state (lexical environment) is a closure.

Simply put: a function that reads variables inside other functions is a closure.

for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(() = > {
      console.log(i)
    }, 1000)
  })(i)
}
Copy the code

2. What is an inner function

In general, a function defined inside another function is called an inner function.

What do closures do?

  1. Use closures to access variables in functions;
  2. You can keep variables in memory for a long time.

4. Memory leaks

1. Memory leakage:

  1. A circular reference
  2. Automatic type boxing conversion
  3. Some of theDOMoperation

(44. Closure

2. Memory leak solution:

  1. Lower than type conversions, which can be avoided by displaying type conversions.
  2. Avoid circular references caused by events;
  3. Dustbin operation;
  4. Manual deletion of variables;

3. Memory leak is a large memory footprint?

No, even 1byte of memory is called a memory leak.

4. The program displays insufficient memory. Is it a memory leak?

No, it is usually infinite recursive function calls, resulting in stack memory overflow.

5. Which area is the memory leak?

The heap area. The stack area does not leak

6. What are the consequences of memory leaks?

In most cases, the consequences are not very serious. But too much DOM manipulation can slow down web pages.

Do memory leaks still exist?

It still exists until the browser closes.

Ten,EventLoopThe execution process of

1. BrieflyEventLoopThe execution process of

  • The wholescriptExecute as a macro task;
  • The synchronized code is executed directly during execution, and the macro task enters the macro task queue and the micro task enters the micro task queue.
  • After the execution of the current macro task is completed, the microtask list is detected, and some microtasks are executed until all the microtask list is executed.
  • Execute browser’sUIThread rendering work;
  • Check if there areweb workerTasks, have to execute;
  • After executing the macro task of this round, go back to step 2 and repeat until the macro task and microtask queues are empty.

2,requestAnimationFrame

Characteristics of 1.

  1. Called before rerendering.
  2. Most likely not called after the macro task.

2. Why is it called before rerendering?

Since rAF is the official recommended API for smooth animation, animation will inevitably change the DOM, and if you change the DOM after rendering, it will have to wait until the next rendering opportunity to draw, which is obviously not reasonable.

RAF gives you one last chance to change the DOM properties before the browser decides to render, and then quickly renders them for you in subsequent drawings, so it’s a great choice for smooth animation.

3,requestIdleCallback

The requestIdleCallback method queues functions that are called during the browser’s idle time. This enables developers to perform background and low-priority work on the main event loop without affecting the delay of critical events such as animations and input responses.

1. Render in an orderly fashion

2. Render long idle

50msEnsures that the user gets a response with no perceived delay.

4,EventLoopCircular attention point

  • Each round of the event cycle may not be accompanied by a highlight, but if there is a microtask, it will be accompanied by a microtask execution.
  • There are many factors that determine whether a browser view is rendered or not, and browsers are very smart.
  • requestAnimationFrameExecuted before rerendering the screen, great for animation.
  • requestIdleCallbackExecute after rendering the screen, and whether there is time to execute depends on the browser’s schedule, if you must execute at a certain time, usetimeoutParameters.
  • resizescrollThe event actually has its own throttling, it only inEvent LoopTo dispatch events to the render phaseEventTargetOn.

5,forCirculation andsetTimeout

Add setTimeout to the for loop

for (var i = 0; i < 10; i++) {
     setTimeout(() = > {
       console.log(i)
     }, 1000)}Copy the code

1. vartolet

for (let i = 0; i < 10; i++) {
  setTimeout(() = > {
    console.log(i)
  }, 1000)}Copy the code

2. Use self-executing functions

for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(() = > {
      console.log(i)
    }, 1000)
  })(i)
}
Copy the code

3. forLoop toforEachcycle

[1.2.3.4].forEach(item= > {
  setTimeout(() = > {
    console.log(item)
  }, 1000)})Copy the code

4. setTimeoutThe ginseng

for (var i = 0; i < arr.length; i++) {
  setTimeout((i) = > {
    console.log(arr[i])
  }, 1000, i)
}
Copy the code

5. Direct output

for (var i = 0; i< 10; i++){
  setTimeout(console.log(i),1000);
}
Copy the code

Eleven,JSIn thelet,const,var

1.JSHow many ways are there to define variables in?

  • let
  • const
  • var
  • class
  • import
  • function

2,let,const,varWhat’s the difference?

var let const
There is no block-level scope There are block-level scopes There are block-level scopes
Declare global variables inwindow Global variables are not under global attributes Global variables are not under global attributes
Redefining a variable does not report an error complains complains
Declare a variable Declare a variable Declare a constant
There is variable promotion There is no variable promotion There is no variable promotion
Assign at any time after the declaration Assign at any time after the declaration Assign immediately after the declaration

3,constCan I change a defined constant?

  1. constDefining base types cannot be modified;
  2. constDefining a reference type allows you to modify the value inside the reference type.

If I want toconstDefining a reference type does not change its value.

  1. Object.freeze;
  2. Agent (proxy/Object.defineProperty);
  3. Modify objectconfigurable,writableProperties.

5, how inES5In this caseletconst?

1. The implementationlet

This can be done by self-executing functions.

2. Implementconst

This can be done with Object.defineProperty() to set writable.

Twelve,JSAn array of

1.ES6New array method

Array.from(), array.of (), copyWithin(), find(), findIndex(), fill(), entries(), keys(), values(), includes().

2,ES5New array method

ForEach (), map(), filter(), some(), every(), indexOf(), lastIndexOf(), reduce(), reduceRight().

3, Which of these array methods can change the original array?

CopyWithin (), fill(), pop(), push(), reverse(), shift(), sort(), splice().

4,someeveryWhat’s the difference?

Some is some, every is every, and both return a Boolean value.

5. There are 100,000 items in the array. Which one will take the first element or the 100,000th element?

The time is basically the same, because there’s no array type in JS, and an array is actually an object, a key and a value.

6, How many methods do you have for array deduplication?

1. Multi-layer cycle traversal method

  • doubleforCycle;
  • Recursive loop.

2. Take advantage of syntax’s own key unrepeatability or API de-duplication

  • ES6 SetGo to the heavy;
  • Create an empty object to remove weight;
  • Single layer circulation +filter/includes/indexOf;
  • Single layer circulation +Map,Objectduplicate removal

7,forCirculation andforEachWhich performance is better?

forLoops perform better

  • forThe loop does not have any additional function call stack or context;
  • forEachNot ordinaryforThe syntax of the loop, as well as the many parameters and contexts that need to be taken into account during execution, can be slow.

Eight,sortIn what way is the sort sorted?

The default sort order is built when converting elements to strings and then comparing their UTF-16 code unit value sequences.

9. Convert multidimensional arrays to one-dimensional arrays

  • reduceThe recursive implementation
  • joinsplitimplementation
  • The recursive traversal
  • flatmethods
  • toStringsplitimplementation
  • Breadth first traversal/depth first traversal

10. How to implement breadth-first and depth-first traversal

JS depth first traversal and breadth first traversal

1. Depth-first traversal

  • Access to the verticesv;
  • In turn, fromvThe graph is traversed depth-first. Until the diagram is neutralvAll vertices with paths connected are accessed.
  • If there are still vertices that are not visited, the depth-first traversal is performed again from an unvisited vertex until all vertices are visited.
const depth = (node) = > {
    let stack = []
    let nodes = []
    if (node) {
        stack.push(node)
        while (stack.length) {
            // Take the last one at a time
            let item = stack.pop()
            let children = item.children || []
            nodes.push(item)
            // Determine the length of children
            for (let i = children.length - 1; i >= 0; i--) {
                stack.push(children[i])
            }
        }
    }
    return nodes
}
Copy the code

2. breadth-first traversal

  • Create a queue and put the start node in the queue;
  • If the queue is not empty, the first node is removed from the queue and detected whether it is the target node.
  • If the target node, the search ends and the result is returned.
  • If not, all its undetected byte points are queued.
  • If the queue is empty, there is no target node in the graph and the traversal ends.
const breadth = (node) = > {
    let nodes = []
    let stack = []
    if (node) {
        stack.push(node)
        while (stack.length) {
            // take the first one
            let item = stack.shift()
            let children = item.children || []
            nodes.push(item)
            for (let i = 0; i < children.length; i++) {
                stack.push(children[i])
            }
        }
    }
    return nodes
}
Copy the code

11. Implement onereduce

Array.prototype.myReduce = function (fn, init) {
    if(! init &&this.length === 0) { // If the array length is 0
        return this
    }
    let start = 1, pre = this[0]; // Start from the second array with subscript 1
    if(init ! = =undefined) { // If init field exists, start with the first one, subscript 0
        start = 0;
        pre = init;
    }
    for (let i = start; i < this.length; i++) { / / loop
        let current = this[i]
        pre = fn.call(this, pre, current, i, this) // Return the value of each reduce
    }
    return pre
}
Copy the code

12, implement a random array shuffling algorithm

function disOrder2 (arr) {
    for (let i = 0; i < arr.length; i++) { / / traverse
        const randomIndex = Math.floor(Math.random() * ary.length) // Generate a random number
        swap(arr, i, randomIndex)
    }
}
function swap(arr, i, _i) { / / exchange
    const tem = arr[i]
    arr[i] = arr[_i]
    arr[_i] = tem  
}
arr = [1.2.3.4.5.6.7.8]
disOrder(arr)
console.log(arr)
Copy the code

13. Separate a string of numbers by commas

1. Regular

num.replace(/(\d)(? =(\d{3})+(\.|$))/g."$1")
Copy the code

2. Traversal

function formatNumber(num) {
  if(! num)return "";
  let [int, float] = num.split(".");
  let intArr = int.split("");
  let result = [];
  let i = 0;
  while (intArr.length) {
    if(i ! = =0 && i % 3= = =0) {
      result.unshift(intArr.pop() + ",");
    } else {
      result.unshift(intArr.pop());
    }
    i++;
  }
  return result.join("") + "." + (float ? float : "");
}
Copy the code

14,map,find,every,some,forEachWhat is the second argument to the etc method?

arr.every(callback(element[, index[, array]])[, thisArg])
Copy the code
  • thisArg

The this value used when executing callback.

Thirteen,for infor ofWhat’s the difference?

To compare for in for of
The difference between You can traverse ordinary objects

Iterate over the array’s prototype object

You can iterate over the array’s own properties

The value that I’m iterating over is zerokey

You can’t iteratemap/set

Can’t iterategenerators

Internet explorer support
Cannot traverse ordinary objects

The prototype object is not iterated over

It doesn’t iterate over its own properties

The value that I’m iterating over is zerovalue

Can traversemap/set

To iterategenerators

IE does not support
The same You can iterate over a number

canbreakInterrupt traversal
You can iterate over a number

canbreakInterrupt traversal

Fourteen,Promise

1. How to implement onesleepFunction (delay function)

This is easily implemented with promises and setTimeout

/** * delay function *@param {Number} Time time * /
function sleep (time = 1500) {
    return new Promise((resolve) = > {
        setTimeout(() = > {
            resolve(true)
        }, time)
    })
}
Copy the code

2,promiseConstructor,thenMethods,catchMethods,finallyWhich methods are asynchronous and which are synchronous?

The Promise constructor is executed synchronously, and the THEN, catch, and finally methods are executed asynchronously.

3. How to cancel onepromise?

Cancel a Promise

1. Usepromise.race()

  • Promise.race(iterable)

When any child promise in the Iterable argument succeeds or fails, the parent promise immediately calls the parent promise’s binding handle using the child promise’s success return value or failure details as arguments and returns the promise object.

/ * * *@author guoqiankunmiss* /
// Encapsulate a function that cancels promises, using the promise.race feature
function stopPromise (stopP) {
	let proObj = {};
	let promise = new Promise((resolve, reject) = > {
		proObj.resolve = resolve;
		proObj.reject = reject;
	})
	proObj.promise = Promise.race([stopP, promise])
	return proObj
}
// A promise for the.then method to be executed 5 seconds later
let promise = new Promise((resolve, reject) = > {
    setTimeout(() = > {
        resolve(123);
    }, 5000);
});
// Call the function
let obj = stopPromise(promise);
// Collect return values
obj.promise.then(res= > {
    console.log(res);
});
// Cancel the Promise operation after two seconds
setTimeout(() = > {
	obj.resolve("The Promise request has been cancelled!");
}, 2000)
Copy the code

More than 4,promiseHow to get the first successpromise?

Get the first successful Promise of multiple promises

1. Promise.allTo improve the

Make use of the promise.all feature, traverse the promise array, judge according to the return value, if successful, to reject return, if failed to resolve continue execution.

// The first successful Promise
function firstProSuccess (allProMise) {
  If the promise array succeeds, reject is returned. If the promise array fails, resolve is returned.
  return Promise.all(allProMise.map(item= > {
    return item.then(
      res= > Promise.reject(res),
      err= > Promise.resolve(err)
    )
  })).then(
    errors= > Promise.reject(errors),
    val= > Promise.resolve(val)
  )
}
Copy the code

2. Promise.any

  • Promise.any(iterable)

Receives a collection of Promise objects, and when one Promise succeeds, returns the value of that successful Promise.

Disadvantages: Compatibility issues

More than 5,promiseAnd all thepromiseReturns the result (returns the value regardless of success/failure)

1. Promise.allTo improve the

This is similar to the previous principle, except that there is no action when successful, and resolve when successful

2. Promise.allSettled()

  • Promise.allSettled(iterable)

Return a promise after all the given promise has fulfilled or Rejected.

Disadvantages: Compatibility issues

6, tell me aboutpromiseWhat are the static methods of?

1. Promise.all(iterable)

Receives a Promise array object (an iterable Promise instance object) and, on success, returns an array of all promises; When one of them fails, the current failed Promise object is returned.

2. Promise.allSettled(iterable)

Receives a Promise array object and returns a new set of Promise arrays when all is done (success/failure)

3. Promise.any(iterable)

Receives an array of Promise objects, and returns a successful promise value when any of them succeed

4. Promise.race(iterable)

Receives an array of Promise objects and returns the promise value when either one succeeds or fails

5. Promise.reject(reason)

Return a Promise object in a failed state.

6. Promise.resolve(value)

Returns a Promise object whose state is determined by the given value.

7. Promise.finally(onFinally)

This will be called after the current promise is fulfilled, no matter the state of the promise is fulfilled or failed.

8. Promise.try(f)

Take a function and return a promise.

It provides a uniform processing mechanism for all operations, so if you want to manage processes with then methods, it’s best to wrap them all in promise.try.

  • Better error handling
  • Better interoperability
  • Easy to navigate

Promise-try

7,Promise.thenDo you understand the second parameter of? and.catchWhat’s the difference?

The then() method returns a Promise.

It needs at most two arguments: a callback to Promise’s success and failure cases.

p.then(onFulfilled[, onRejected]);
p.then(value= > {
  // fulfillment
}, reason= > {
  // rejection
});
Copy the code

The second argument is also a function that is a callback to the failure case.

thenSecond parameter catch
thenMethod parameters PromiseInstance method of
thenThe first argument to throw an exception is not caught The first argument to then throws an exception that can be caught
It’s a function Nature isthenMethod syntax sugar
If the second argument is equal tocatchCoexisting,promiseInternal error, second parameter can be captured At this point,catchThe second parameter does not exist.catchTo capture it
Not recommended It is recommended to usecatchError capture

Eight,Promise.resolveHow many cases are there?

1. The parameter is onePromiseThe instance

If the argument is a Promise instance, promise.resolve will return the instance unchanged.

2. The parameter is onethenableobject

The promise.resolve () method turns this object into a Promise object and immediately executes the thenable object’s then() method.

3. The parameter does not existthen()Method object, or not object at all

If the parameter is a raw value, or an object that does not have a then() method, the promise.resolve () method returns a new Promise object with the state Resolved.

4. No parameters

Return an Resolved Promise object directly.

9, if.thenWhat if the arguments in the.

Promise.resolve(1)
    .then(2)
    .then(console.log)
/ / 1
Copy the code

If the argument in.then is not a function, it is internally replaced with (x) => x, the function that returns the final result of the promise as is.

10, if.finallyFollowed by another.thenSo thisthenWhat are the values inside?

Promise.resolve('resolve')
  .finally(() = > {
    console.log('this is finally')
    return 'finally value'
  })
  .then(res= > {
    console.log(The then function after 'finally 'has the value res:', res)
  })
// this is finally
Copy the code

The then function after finally, res, has the value: resolve

  1. finallyDoes not accept any arguments in the callback function of
  2. inpromiseAt the end of the day, whatever the result isfulfilledOr is itrejected, will be implementedfinallyCallback function;
  3. finallyThe return is a previous onePromiseObject value.

11,.all.raceDo other asynchronous tasks continue when the first exception is thrown in the passed array?

Yes, it will continue, just not in then/catch.

When the browser executes the following code, you can see that console continues to execute when an error is reported, but it is not shown in the corresponding callback function.

function sleep (n) {
    return new Promise((resolve, reject) = > {
        console.log(n)
        Math.random() > 0.5 ? reject(n) : resolve(n)
    }, n % 2= = =0 ? 1000 * n : 1000)}Promise.all([sleep(1), sleep(2), sleep(3)])
  .then(res= > console.log('all res: ', res))
  .catch(err= > console.log('all err:', err))
Promise.race([sleep(1), sleep(2), sleep(3)])
  .then(res= > console.log('race res: ', res))
  .catch(err= > console.log('race err:', err))
Copy the code

12,.allIs it concurrent or serial?

Is concurrent, but returns values in the same order as the array received in promise.all.

13,promiseWhy can you make chain calls

Because the then, catch, and finally methods return a new promise, we are allowed to make chain calls.

14,async/await

1. Implementation principle

Async function is implemented based on generator, so it involves knowledge about generator. In the absence of async functions, the CO library is usually used to execute the generator, so we can emulate async implementation with CO.

2. Simple implementation

1)co
function Asyncfn() {
  return co(function* () {
    / /...
  });
}
function co(gen) {
  return new Promise((resolve, reject) = > {
    const fn = gen();
    function next(data) {
      let { value, done } = fn.next(data);
      if (done) return resolve(value);
      Promise.resolve(value).then(res= > {
        next(res);
      }, reject);
    }
    next();
  });
}
Copy the code
2)GeneratorFunctions and self-effectors
function spawn(genF) {
    return new Promise(function(resolve, reject) {
        const gen = genF();
        function step(nextF) {
            let next;
            try {
                next = nextF();
            } catch (e) {
                return reject(e);
            }
            if (next.done) {
                return resolve(next.value);
            }
            Promise.resolve(next.value).then(
                function(v) {
                    step(function() {
                        return gen.next(v);
                    });
                },
                function(e) {
                    step(function() {
                        returngen.throw(e); }); }); } step(function() {
            return gen.next(undefined);
        });
    });
}
Copy the code

15. Tell meJSON.stringifyJSON.parse

1.JSON.stringify

Definition: Converts a JavaScript object or value to a JSON string. Parameters: There are three parameters

JSON.stringify(value[, replacer [, space]])
Copy the code
  1. replacer

The replacer argument can be a function or an array. As a function, it takes two arguments, a key and a value, both of which are serialized. Replacer is an array whose value represents the name of the property to be serialized into a JSON string. The space argument controls the spacing within the resulting string. If it is a number, each level of stringification will indent more Spaces of the value of that number than the previous level; If it is a string, each level indents the string more than the previous level.

2,JSON.parse

Definition: Used to parse JSON strings. Parameters: There are two parameters

JSON.parse(text[, reviver])
Copy the code
  1. reviver

The converter, if passed, can be used to modify the original parsed value.

features

  1. Convert value if anytoJSON()Method that defines what values will be serialized.
  2. Properties of non-array objects are not guaranteed to appear in a serialized string in a particular order.
  3. Booleans, numbers, and string wrapper objects are automatically converted to their original values during serialization.
  4. undefined, any function andsymbolValue is ignored during serialization (when present in an attribute value of a non-array object) or converted tonull(when appearing in an array). The function,undefinedReturns when converted separatelyundefined, such asJSON.stringify(function(){}) or JSON.stringify(undefined).
  5. Executing this method on objects that contain circular references (objects that refer to each other in an infinite loop) throws an error.
  6. All tosymbolProperties that are property keys are completely ignored, even if they are mandatory in the replacer parameter.
  7. DateDate is calledtoJSON()Convert it tostringString (same asDate.toISOString()), so it is treated as a string.
  8. NaNInfinityThe value of the format andnullWill be regarded asnull.
  9. Other types of objects, includingMap/Set/WeakMap/WeakSetOnly enumerable attributes are serialized.

16,= =,= = =Object.is()

1, the difference between

  • = =If the two values have different types, perform type conversion first and then compare
  • = = =Direct value comparison without type conversion
  • Object.is(val1, val2)Determines whether two values are the same

2,= =How do type conversions work?

  1. If the type is different, cast it
  2. Determine if you are comparingnullOr is itundefinedIf so, returntrue
  3. Check whether the type isstringornumber, if so, willstringconvertnumber
  4. Determine if either party isbooleanIf so, convert one of the parties tonumberJudging
  5. Determine if either party isobjectAnd the other party isstring,number,symbol, if so, willobjectTo determine the original type (valueOf()Methods)
  6. If one of them isNaN, directly returnsfalse
  7. If both are objects, it compares whether they refer to the same object

3,[] = =! []What is the value of?

Answer: True

The transformation steps

  1. ! The operator has the highest precedence,! []Will be converted tofalse, so at this time is[] == false
  2. According to Article 4, one of the parties isboolean,booleantonumber, so at this time is[] = = 0
  3. And then according to number five, put the array[]To the original type, call the arraytoString()Method,[].toString() = '', so at this time is' '= = 0
  4. And according to rule number three, thestringtonumber.' 'tonumberPhi is zero, so at this point0 = = 0
  5. The data type on both sides is the same0 = = 0fortrue

4, object.is () check if two values are equal

No cast is performed

  • Are allundefined
  • Are allnull
  • Are alltruefalse
  • Are strings of the same length and the same characters are arranged in the same order
  • Are the same objects (meaning each object has the same reference)
  • It’s all numbers and
    • Are all+ 0
    • Are all0
    • Are allNaN
    • Or both are non-zero and notNaNAnd are the same value

Seventeen, shake and throttling

1. What is anti-shake and throttling

Anti – shake: indicates that multiple execution is changed to last throttling. Indicates that multiple execution is changed to every period of time

2. Simple anti-shake and throttling

1. Achieve anti-shake

The function is executed only once within n seconds after the high-frequency event is triggered. If the high-frequency event is triggered again within n seconds, the time will be recalculated and the previous delayed call method will be cancelled each time the event is triggered

function debounce (fn, time = 500) {
  let timeout = null; // Create a flag to store the return value of the timer
  return function () {
    clearTimeout(timeout) // When triggered, clear the previous timer
    timeout = setTimeout(() = > { // Create a new timer and assign it to timeout
      fn.apply(this.arguments)
    }, time)
  }
}
function testDebounce () {
  console.log('Test anti-shake')}const inp = document.getElementById('testInp')
inp.addEventListener('input', debounce(testDebounce))
Copy the code

2. Throttling implementation

A high-frequency event is triggered, but it will only be executed once within n seconds. Therefore, throttling will dilute the execution frequency of the function, and each time the event is triggered, it will determine whether there is a delay function waiting to be executed

function throttle (fn, time = 100) {
  let timeout;
  return function () {
    let context = this
    let args = arguments
    if(! timeout) { timeout =setTimeout(() = > {
        timeout = null
        fn.apply(context, args)
      }, time)
    }
  }
}
function testThro () {
  console.log('Test throttling')}const inp = document.getElementById('testInp')
inp.addEventListener('input', throttle(testThro))
Copy the code

Eighteen,cookie,sessionStoragelocalStorage

1, the three differences

  • cookieUsed to save login information, size limit is4KBOr so
  • localStorageHtml5New, used for local data storage, stored data does not expire, the general browser size limit5MB
  • sessionStorageInterface methods andlocalStorageSimilar, but saved data will only be saved in the current session, the page will be cleared after closing.
The name of the Life span Size limit Communicating with the server Whether it can cross domains
cookie Generally, it is generated by the server. You can set the expiration time. If generated on the browser sideCookieIs disabled after the browser is closed by default 4KB I carry it with me every timeHTTPHeader, if usedcookieStoring too much data can cause performance problems Generally not, samedomainCan allow the interface request to carrycookie
localStorage It is stored permanently unless it is removed 5MB It is saved only in the browser and does not communicate with the server Do not
sessionStorage This parameter is valid only in the current session and is cleared after you close the page or browser 5MB It is saved only in the browser and does not communicate with the server Do not

2,localStorageHow does cross-domain storage work?

LocalStorage is not allowed to carry out cross-domain operations, but to carry out cross-domain operations can use postMessage, webSocket disguised cross-domain operations.

19. Cross-domain browser problems

1. What is the browser same-origin policy?

The same origin policy is an important security policy, which is used to restrict how an Origin document or its loaded script can interact with another source. It can help block malicious documents and reduce the media that can be attacked.

The same origin policy refers to the same origin policy only at the address:

  1. Agreement,
  2. The domain name
  3. The port name

Only in the same case, the same cookie, localStorage, and DOM access to the page or send Ajax requests are allowed.

2. What are the dangerous scenarios without the same-origin policy restriction?

  • ajxarequest
  • DomThe query

The same origin policy can avoid some risks. It does not mean that the same origin policy is secure, but it is a basic security mechanism for browsers. After all, the same origin policy can increase the cost of attacks.

3. Why do browsers prohibit cross-domains?

  • Cross-domain only exists on the browser side, which needs to be restricted because of the open form of the browser.
  • The same origin policy is used to protect user information and prevent malicious data theft (ajaxSame origin policy,DomSame-origin policy).

4. What are the cross-domain solutions?

CSDN cross domain problem solving

  1. jsonp
  2. cors
  3. postMessage
  4. websocket
  5. NodeMiddleware proxy (cross domain twice)
  6. nginxThe reverse proxy
  7. window.name + iframe
  8. location.hash + iframe
  9. document.domain + iframe

5,CORSWhat are the common configurations?

  • Access-Control-Allow-OriginAllowed domain name
  • Access-Control-Allow-MethodsAllow thehttpRequest method
  • Access-Control-Allow-HeadersSupported request headers
  • Access-Control-Allow-CredentialsWhether to sendcookie
  • Access-Control-Max-AgeCache time in seconds

6,CORSDecision flow across domains

  1. The browser checks whether the data is of the same origin. If the data is of the same origin, the browser directly sends the data. Otherwise, the browser sends the cross-domain request.
  2. After receiving the cross-domain request, the server returns the corresponding file header based on its own configuration.
  3. The browser based on the received response headerAccess-Control-Allow-originIf the field does not exist, cross-domains cannot be allowed, and an error is reported. If the field is available, cross-domains can be determined.

What is a simple request?

A simple request is one that meets the following conditions:

  • useget,post,headOne of these methods of making a request;
  • httpThe header information does not exceed the following situations:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID

Content-type: Values are limited to Application/X-www-form-urlencoded, multipart/form-data, text/plain

  • In the requestXMLHttpRequestUploadObject does not register any event listeners;
  • XMLHttpRequestUploadObjects can be usedXMLHttpRequest.uploadProperty access. Not used in the requestReadableStreamObject.

8. Non-simple requests

Requests that have special requirements on the server (other than simple requests are non-simple requests).

For example, the request mode is PUT or delete, and the content-type is Application/JSON.

Non-simple requests initiate a pre-check request using options before formal communication, asking the server if the current domain name is on the server’s allowed list and which header fields to use.

9. What are the methods for embedding cross-source resources?

  • scriptTags to embed cross-domain scripts;
  • linkTag, embedcss;
  • imgTags, embedded images;
  • video/audioLabel, embedded video, audio;
  • object/embed/appletTag, embedsvg/ pictures, etc.;
  • svgTag, embedsvg;
  • through@font-faceEmbedded font;
  • throughiframeEmbedded resources

10. Implement one manuallyJSONP

/ / Promise encapsulation
function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) = > {
    // Create the script tag
    let script = document.createElement('script')
    // Mount callback to window and delete script after execution
    window[callback] = function(data) {
      resolve(data)
      document.body.removeChild(script)
    }
    // Add parametersparams = { ... params, callback }// wd=b&callback=callFun
    let arrs = []
    for (let key in params) {
      arrs.push(`${key}=${params[key]}`)}// Set the script URL
    script.src = `${url}?${arrs.join('&')}`
    // Insert into body
    document.body.appendChild(script)
  })
}
// Call an example
jsonp({
  url: 'http://localhost:3000/code'.params: { wd: 'hello world' },
  callback: 'callFun'
}).then(data= > {
  console.log(data) / / hello
  // Delete the script after the callback
})
Copy the code

20. Tell mejsInheritance mode of

JS common six types of inheritance

1. Prototype chain inheritanceprototype

The prototype of a child type is an instance object of the parent type.

Child.prototype = new Parent()
Copy the code

Advantages:

  1. Simple inheritance
  2. New methods and attributes in the parent class can be accessed by subclasses

Disadvantages:

  1. Multiple inheritance cannot be implemented
  2. All attributes from the parent class are shared by all instances
  3. If you want to add attributes and methods to a Child class, it must be after child.prototype = new Parent(), because it will be overridden
  4. When creating a subclass, you cannot pass arguments like the parent class

Constructor inheritancecall

The generic call() in the subtype constructor calls the parent type constructor

function Child(name, age, price) {
    Parent.call(this, name, age)  // equivalent to: this.parent (name, age)
}
Copy the code

Advantages:

  1. The problem of subclass instances sharing parent class reference properties in stereotype chain inheritance
  2. When you create a subclass instance, you can pass parameters to the parent class
  3. Multiple inheritance can be implemented (call multiple parent objects)

Disadvantages:

  1. An instance is not an instance of a parent class, only an instance of a subclass
  2. Only instance properties and methods of the parent class can be inherited, not stereotype properties and methods
  3. Function reuse is not possible, each subclass has a copy of the parent class instance function, affecting performance

3. Combinatorial inheritance of prototype chain + constructorprototype + call

Call the superclass constructor, inherit the attributes of the superclass and retain the advantages of passing arguments, then reuse the function by using the instance of the superclass as the prototype of the subclass.

function Child (name, age, price) {
  Parent.call(this, name, age)
}
Child.prototype = new Parent()
Child.prototype.constructor = Child// Composite inheritance also needs to be fixed to the constructor point
Copy the code

Advantages:

  1. You can inherit instance properties/methods as well as stereotype properties/methods
  2. There is no reference property sharing problem
  3. Can pass the cords

Disadvantages:

  1. The parent constructor is called twice, generating two instances

4. Combinatorial inheritance optimization 1

By referring to the same object as the parent stereotype, a subclass can inherit the parent class’s public methods as its own, without initializing methods/attributes twice, avoiding the drawback of combinatorial inheritance.

function Child (name, age, price) {
    Parent.call(this, name, age)
}
Child.prototype = Parent.prototype
Copy the code

Advantages:

  1. The superclass constructor is never called twice

Disadvantages:

  1. There is no way to tell whether the instance was created by a subclass or a superclass. The subclass and the superclass have the same constructor pointing to the same object.

5. Combinatorial inheritance optimization 2

Var B = object.create (A) creates an Object based on an existing Object. B inherits all of A’s properties and methods.

function Child (name, age, price) {
    Parent.call(this, name, age)
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
Copy the code

6,es6 classThe inheritance of

The class keyword is just syntactic sugar for the stereotype, and JavaScript inheritance is still implemented based on the stereotype.

class Parent {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    setName () {
        console.log('parent')}}let child1 = new Parent('name1'.18)
let child2 = new Parent('name2'.16)
class Child extends Parent {
    constructor(name, age, price) {
        super(name, age)
        this.price = price
    }
    setAge () {
        console.log('Subclass method')}}let child3 = new Child('name3'.20.15000)
let child4 = new Child('name4'.21.10000)
Copy the code

Advantages:

  1. Simple inheritance

Xxi. Sorting algorithm

1. Bubble sort

Simply put, compare two adjacent elements and replace them in any order you want (ascending or descending), with an extra variable used as an intermediate variable to temporarily store values.

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = 0; i < len; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {        // Compare adjacent elements in pairs
                var temp = arr[j+1];        // Element swap
                arr[j+1] = arr[j]; arr[j] = temp; }}}return arr;
}
Copy the code

2. Quicksort

Select a baseline and place the one less than the baseline to the left and the one less than the baseline to the right (baseline is in the middle)

function quickSort(arr) {
    // If the array <=1, it returns directly
    if (arr.length <= 1) { return arr; }
    var pivotIndex = Math.floor(arr.length / 2);
    // Find the benchmark and delete it from the original array
    var pivot = arr.splice(pivotIndex, 1) [0];
    // Define left and right arrays
    var left = [];
    var right = [];
    // Smaller than the baseline is placed left, larger than the baseline is placed right
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] <= pivot) {
            left.push(arr[i]);
        }
        else{ right.push(arr[i]); }}/ / recursion
    return quickSort(left).concat([pivot], quickSort(right));
}
Copy the code

3. Selection sort

Find the smallest element from the original array and place that element at the top of the array. Then find the smallest element from the remaining elements and place it behind the previous smallest element until the order is complete

function selectionSort(arr) {
    var len = arr.length;
    var minIndex, temp;
    for (var i = 0; i < len - 1; i++) {
      minIndex = i;
      for (var j = i + 1; j < len; j++) {
        if (arr[j] < arr[minIndex]) {
          minIndex = j;
        }
      }
      temp = arr[i];
      arr[i] = arr[minIndex];
      arr[minIndex] = temp;
    }
    return arr;
}
Copy the code

4. Insert sort

Starting from the second element (assuming the first element has been sorting), remove the element, in already sorted elements from forward after the comparison, if the element is greater than the element, just move the element to the next place, and then move on, until you find less than or equal to the element’s position, insert the element to this location. Repeat this step until the sorting is complete

function insertionSort(arr) {
  var len = arr.length;
  var preIndex, current;
  for (var i = 1; i < len; i++) {
    preIndex = i - 1;
    current = arr[i];
    while (preIndex >= 0 && arr[preIndex] > current) {
      arr[preIndex + 1] = arr[preIndex];
      preIndex--;
    }
    arr[preIndex + 1] = current;
  }
  return arr;
}
Copy the code

5. Merge sort

Merge sort is an efficient sorting algorithm based on merge operation. The algorithm adopts divide-and-conquer method (Divide and ConquerA very typical application of. Merge sort is a stable sorting method. The ordered subsequences are combined to obtain a fully ordered sequence. That is, each subsequence is ordered first, and then the subsequence segments are ordered. If two ordered tables are joined into one ordered table, it is called 2-way merge.

function mergeSort(arr) {  // Use a top-down recursive approach
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right){
    var result = [];
    console.time('Merge sort time');
    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else{ result.push(right.shift()); }}while (left.length)
        result.push(left.shift());
    while (right.length)
        result.push(right.shift());
    console.timeEnd('Merge sort time');
    return result;
}
Copy the code

Hill sort

Use the step size to compare pairwise elements, and then reduce the step size for sorting. Note: The essence of Hill sort is group insertion sort, which is also called reduced increment sort. The basic idea of the method is: will first stay the whole row element sequence is divided into several sub sequence (composed of elements separated by a “delta”) direct insertion sort, respectively, and then in turn to cut incremental sort, with the sequence of elements in the basic order (increment is small enough, again to all the elements on a direct insertion sort. Because direct insertion sort is efficient when the elements are basically ordered (close to the best case), Hill sort has a large improvement in time efficiency. Differences from insertion sort:It compares the more distant elements first

function shellSort(arr) {
  let temp,
    gap = 1;
  while (gap < arr.length / 3) {
    gap = gap * 3 + 1// Dynamically define interval sequences
  }
  for (gap; gap > 0; gap = Math.floor(gap / 3)) {// Control the step size (interval) and keep shrinking
    for (var i = gap; i < arr.length; i++) {// Sort the sequence by the number of increments
      temp = arr[i]
      for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {// example: j=0 arr[1]>arr[5]
        arr[j + gap] = arr[j]
      }
      arr[j + gap] = temp
    }
  }
  return arr
}
Copy the code

7. Comparison of various sorting algorithms

Time complexity and space complexity

1. How to measure the advantages and disadvantages of different algorithms?

Mainly from the algorithm occupied by the “time” and “space” two dimensions to consider.

  • Time dimension: Refers to the time taken to execute the current algorithm, which is usually described by “time complexity”.
  • Spatial dimension: Refers to the amount of memory required to perform the current algorithm, which is usually described as “spatial complexity”.

2. Time complexity

1. Presentation method

Big O notation, that is T(n) = O(f(n))

The formula of time complexity is: T(n) = O(f(n)), where F (n) represents the sum of times of execution of each line of code, and O represents the direct proportional relationship. The full name of this formula is: progressive time complexity of the algorithm.

2. Common complexity levels

• constant order O(1) • log order O(logN) • linear order O(nlogN) • linear log order O(nlogN) • square order O(n^ 2) • cubic order O(n^ 3) • K order O(n^ K) • exponential order 2^n

3. O(1)

It doesn’t matter how many lines of code it executes, as long as it doesn’t have loops or anything, the time complexity of the code is O(1).

var i = 1;
var j = 2;
++i;
j++;
var m = i + j;
Copy the code

4. O(n)

The code inside the for loop executes n times, so the time it takes varies with n, so this type of code can be expressed as O(n).

for(i=1; i<=n; ++i)
{
   j = i;
   j++;
}
Copy the code

5. The logarithmic orderO(logN)

var i = 1;
while(i<n)
{
    i = i * 2;
}
Copy the code

In the while loop, every time you multiply I by 2, you get closer and closer to n. So let’s try to solve for it, assuming that after x times, I is greater than 2, and then the loop ends, which means that 2 to the x is equal to n, so x is equal to log2 to the n which means that after x to the log2 to the n, this code ends. So the time complexity of this code is O(logn).

6. O(nlogN)

If you loop O(logn) code N times, it’s N times O(logn), which is order N (logn).

for(m=1; m<n; m++)
{
    i = 1;
    while(i<n)
    {
        i = i * 2; }}Copy the code

7. O (n squared),O(m*n),O (n) after,O(n^k)

Order O(n ^ 2), the code of O(n) is nested and looped again, and its time complexity is O(n*n), which is O(n ^ 2).

for(x=1; i<=n; x++)
{
   for(i=1; i<=n; i++) { j = i; j++; }}Copy the code

O(m*n) changes the n of one layer to m, and its time complexity becomes O(m*n).

for(x=1; i<=m; x++)
{
   for(i=1; i<=n; i++) { j = i; j++; }}Copy the code

3. Spatial complexity

Space complexity is a measure of the amount of storage space temporarily occupied by an algorithm during its operation. It also reflects a trend and is defined by S(n).

1. Common complexity levels

Space complexity is commonly used: O(1), O(n), O(n²).

2. O(1)

If the temporary space required for algorithm execution does not change with the size of a variable N, that is, the space complexity of this algorithm is a constant, which can be expressed as O(1).

var i = 1;
var j = 2;
++i;
j++;
var m = i + j;
Copy the code

The space allocated by I, j and M in the code does not change with the amount of data processed, so its spatial complexity S(n) = O(1)

3. O(n)

var arr = [1.2.3]
for(i=1; i<=arr.lemgth; ++i)
{
   j = i;
   j++;
}
Copy the code

The first line defines an array, and the size of this data is N. For lines 2-6 of this code, there is a loop, but no new space is allocated. Therefore, the space complexity of this code is mainly based on the first line, that is, S(n) = O(n).

23. Interface request

1.AJAX

1, simple implementation of oneajax

function stringify (json) {
  var str = "";
  for (var i in json) {
    str += i + "=" + json[i] + "&";
  }
  return str.slice(0, -1);
}
function myAjax (type, url, params, callback, errback) {
  let xhr = null;
  IE / / table
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }
  if (type == "get") {
    xhr.open(type, url + "?" + stringify(params), true);
    xhr.send();
  } else {
    xhr.open(type, url, true);
    xhr.setRequestHeader('Content-Type'.'application/x-www-form-urlencoded');
    //json converts to name= age=1
    xhr.send(stringify(params));
  }
  xhr.onreadystatechange = function () {
    // Indicates that the request is complete
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        if(callback) { callback(xhr.responseText); }}else{ errback && errback(); }}}}Copy the code

2,ajaxreadyStateThe state of the

  • 0Uninitialized, not called yetopen()methods
  • 1Start, already calledopen()Method, but not calledsend()methods
  • 2Send, already calledsend()Method, but no response has been received
  • 3Received. Partial response data has been received
  • 4Complete. All response data has been received

2,Axios

Axios is essentially a wrapper around the native XHR, but it’s an implementation of Promise that meets the latest ES specification

1. Features:

  • fromnode.jscreatehttprequest
  • supportPromise API
  • Client support preventsCSRF
  • Provides some interfaces for concurrent requests (important, much easier to do)

3,Fetch

The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method, which provides a simple, reasonable way to fetch resources asynchronously across a network.

1. The advantages

  • Syntax concise, more semantic
  • Based on the standardPromiseImplementation, supportasync/await
  • Isomorphism is easy to useisomorphic-fetch

2. The shortcomings

  • FetchThe request is not brought by defaultcookieNeed to be setfetch(url, {credentials: 'include'})
  • The server does not return 400,500 error codesreject, and only network errors such as these prevent the request from being completed.fetchWill bereject.

24,newThe operator

1.newImplementation process of

  • Create a new object.
  • 2. Assign the scope of the constructor to the new object (hencethisIt points to the new object);
  • 3. Execute the code in the constructor (add attributes to the new object);
  • 4. Return a new object.
  • 5. Put the constructor’sprototypeAssociated with the instance__proto__

2. How to implement onenew

function myNew (foo, ... args) {
  // Create a new object and inherit foo's prototype property
    let obj = Object.create(foo.prototype)
  // execute the constructor and bind the new this,
  let result = foo.apply(obj, args)
  // If the constructor returns an object, then that object is returned, otherwise a new object created by myNew is returned
  return Object.prototype.toString().call(result) === '[object Object]' ? result : obj
}
Copy the code

How to achieve full screen web page?

document.documentElement.requestFullscreen()
Copy the code

Need compatible implementation

1. Full screen web page

function fullScreen() {
    if (!document.fullscreenElement &&
        !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { // current working methods
        if (document.documentElement.requestFullscreen) {
            document.documentElement.requestFullscreen();
        } else if (document.documentElement.msRequestFullscreen) {
            document.documentElement.msRequestFullscreen();
        } else if (document.documentElement.mozRequestFullScreen) {
            document.documentElement.mozRequestFullScreen();
        } else if (document.documentElement.webkitRequestFullscreen) {
            document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); }}}Copy the code

2. Cancel full screen

function exitFullScreen() {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen(); }}Copy the code

3. Check whether the screen is full

/** * Check whether full screen *@return {[Boolean]} [Full screen, true no full screen, false full screen] */
function checkFullScreenValue () {
    return !document.fullscreenElement &&
        !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement
}
Copy the code

26,Map,WeakMapset,WeakSetWhat’s the difference?

WeakMap and WeakSet are both weak references

1. What is weak reference

A weak reference is a reference that cannot be guaranteed that the object it refers to will not be collected by the garbage collector; in other words, it may be collected at any time.

Weak references disappear at any time, and traversal mechanisms cannot guarantee the existence of members

2,Set

  • Traversal order: Insert order
  • There are no keys and only values, so the key and value can be considered equal
  • Add multipleNaN, there will only be oneNaN
  • When the same object is added, it is considered a different object
  • No type conversion occurs when values are added (5! = = "5")
  • keys()values()In exactly the same way,entries()The traverser returned contains both a key and a value that are equal

3,weakSetrole

  • andSetThe structure is similar in that member values can only be objects
  • storageDOMNodes:DOMThis member is automatically released when nodes are removed without worrying about memory leaks when these nodes are removed from the document
  • To temporarily store a group of objects or information bound to them: as long as these objects disappear externally, it will remainWeakSetReferences in the structure are automatically eliminated
  • Members are weak references and are not considered by the garbage collection mechanismWeakSetStructure a reference to this member
  • The member is not suitable for reference, it will disappear at any time, thereforeES6provisionsWeakSetThe structure is not traversal
  • When other objects no longer reference a member, the garbage collection mechanism automatically reclaims the memory occupied by the member, regardless of whether the member still existsWeakSetIn the structure

4,Map

  • Traversal order: Insert order
  • If the same key is assigned more than once, the subsequent value overrides the previous value
  • A reference to the same object is treated as a key
  • Two instances of the same value are treated as two keys
  • The key is bound to the memory address, and as long as the memory address is different, it is regarded as two keys
  • Add more than oneNaNAs a key, there will only be oneNaNAs the value of the key
  • ObjectStruct provides string-value correspondence,MapStructure provides value – value correspondence

5,WeakMap

  • andMapSimilarly structured, member keys can only be objects
  • storageDOMNodes:DOMThis member key is automatically released when nodes are removed without worrying about memory leaks when they are removed from the document
  • Deploy private properties: Internal properties are weak references to the instance and disappear when the instance is deleted without causing a memory leak
  • Member keys are weak references and are not considered by the garbage collection mechanismWeakMapStructure a reference to this member key
  • The member key is not suitable for reference, it will disappear at any time, soES6provisionsWeakMapThe structure is not traversal
  • When other objects no longer reference a member key, the garbage collection mechanism automatically reclaims the memory occupied by the member, regardless of whether the member still existsWeakMapIn the structure
  • Once no longer needed, the member disappears automatically, without manually removing the reference
  • Weak references are only keys, not values, and values are still normal references
  • Even if references to member keys are removed externally, the internal member values remain

6,ObjecttoMap

let obj = {"a":1."b":2};
let map = new Map(Object.entries(obj))
Copy the code

27,Proxy

1, grammar,

  • targetIn order to useProxyThe wrapped target object (can be any type of object, including a native array, a function, or even another proxy
  • handlerAn object, usually with a function as a property, used to customize interception behavior

The proxy only applies to proxy objects, and has no effect on proxy objects

origin = {}
obj = new Proxy(origin, {
  get: function (target, propKey, receiver) {
        return '10'}}); obj.a/ / 10
obj.b / / 10
origin.a // undefined
origin.b // undefined
Copy the code

2,HandlerObject common methods

methods describe
handler.has() inOperator.
handler.get() The catcher for the property read operation.
handler.set() Property set the catcher for the operation.
handler.deleteProperty() deleteOperator.
handler.ownKeys() Object.getOwnPropertyNamesMethods andObject.getOwnPropertySymbolsMethod.
handler.apply() A catcher for a function call operation.
handler.construct() newOperator
# # # 3,proxyCan an agent be revoked?
proxyThere is a unique static method,Proxy.revocable(target, handler)
Proxy.revocable()Method can be used to create a revocable proxy object
The return value of this method is an object of the structure: {"proxy": proxy, "revoke": revoke}
  • proxyRepresents the newly generated proxy object itself, and in the general waynew Proxy(target, handler)The created proxy object is no different, except that it can be undone.
  • revokeThe undo method is called to undo the proxy object it was created with without any arguments.
const target = { name: 'vuejs'}
const {proxy, revoke} = Proxy.revocable(target, handler)
proxy.name // The normal value is vuejs
revoke() // Close the proxy and cancel the proxy
proxy.name // TypeError: Revoked //
Copy the code

Execution Context

What is the type of execution context?

1. Global execution context

Only one global execution context can exist in a program.

This is the default, most basic execution context. Code that is not in any function is in the global execution context. It does two things:

  1. Create a global object, which in the browser is the global objectwindowObject.
  2. willthisThe pointer points to this global object.

2. Function execution context:

There can be an infinite number of function execution contexts.

Each time a function is called, a new execution context is created for that function. Each function has its own execution context, but is created only when the function is called.

3. EvalFunction execution context:

The code inside the JS eval function creates its own execution context, which is rarely used and is not recommended.

2. Characteristics of execution context

  1. Single thread;
  2. Synchronous execution, execution from top to bottom;
  3. There is only one global context, i.ewindowObject;
  4. There is no limit to the number of function execution contexts;
  5. Functions are created only when they are called, and a new execution context is created each time they are called.

3. Lifecycle of execution context

1. Creation phase

  1. Create a variable object: first initialize the parameters of the functionarguments, and promote function declarations and variable declarations.
  2. Create scope chain: The scope chain is created after the variable object. The scope chain itself contains variable objects. Scope chains are used to resolve variables. When asked to parse a variable,JavaScriptAlways start at the innermost layer of code nesting, and if the innermost layer does not find the variable, jump to the parent scope until the variable is found.
  3. determinethisPoint to: ConfirmthisPointing to.

2. Implementation phase

  1. Perform variable assignment.
  2. Function references.
  3. Execute other code.

3. Recycling phase

  1. Perform context ejection
  2. Wait for the VIRTUAL machine to reclaim the execution context

4,jsHow to manage multiple execution contexts?

Managing multiple execution contexts is the execution stack, also known as the call stack.

Features: LIFO: last-in, first-out (LIFO) structure. Action: Stores all execution contexts during code execution.

Example:

var a = 1; // 1. Global context
function bar (x) {
    console.log('bar')
    var b = 2;
    fn(x + b); // 3. fn context
}
function fn (c) {
    console.log(c);
}
bar(3); // 2. Bar context
Copy the code

Implement some special functions

1. One-time functions

function once (func) {
  let done;
  return function () {
    if(! done) { func.apply(null.arguments)
      done = true}}}const onlyDoOne = once(function() {
  console.log('1')
})
onlyDoOne() / / 1
onlyDoOne() // If there is no output, it will not be executed again
Copy the code

2. Delay function (sleeping function)

function sleep (time) {
    return new Promise(resolve= > {
    window.setTimeout(resolve, time)
  })
}
/ / call
sleep(1000).then(res= > {
    console.log('delay')})/ / call
async function useSleep () {
    const sleepval = await sleep(1000)
}
useSleep()
Copy the code

3,setTimeoutimplementationsetInterval

; (() = > {
  const list = new Set(a);function myInterval(fn, ms) {
    const ref = {};
    const exec = () = > {
      return setTimeout(() = > {
        fn.apply(null);
        const timer = exec();
        ref.current = timer;
      }, ms);
    };
    ref.current = exec();
    list.add(ref);
    return ref;
  }
  function myClearInterval(ref) {
    clearTimeout(ref.current);
    list.delete(ref);
  }
  window.myInterval = myInterval;
  window.myClearInterval = myClearInterval;
})()
myInterval(() = > {console.log(1)}, 5000)
myClearInterval({current: 1186})
Copy the code

4. Front-end generationexcelForm and download

/** * front-end download table *@param  {[Array]} Data [data array] *@param  {[String]} TableHead [table header string] *@return {[undefined]}           * /
function downExcel (data, tableHead) {
  tableHead = tableHead
  data.forEach(item= > {
    for (let i in item) {
      tableHead += `${item[i] + '\t'}, `
    }
    tableHead += '\n'
  })
  const url = 'data:text/csv; charset=utf-8,\ufeff' + encodeURIComponent(tableHead);
  // By creating the a tag
  const link = document.createElement("a");
  link.href = url;
  // Name the downloaded file
  link.download = "My EXCEL spreadsheet. CSV.";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}
/ / the excel data
let tableData = [{
  name: 'Hello.'.time: 130000000000.pre: '127.130'.source: 'taobao'.otherTime: 1571276232000
}]
/ / excel in the head
let str = 'username, time, coordinates, source, authorization time \n';
// Download the form execution
downExcel(tableData, str)
Copy the code

What is a prototype, a prototype chain?

Prototype: When JS declares a constructor (a function used to instantiate an object), it creates a corresponding object in memory that is the prototype of the original function.

By default, the constructor has a prototype property whose value points to the function’s prototype. The stereotype also has a constructor property, whose value points to the original function.

An object instantiated by a constructor does not have a prototype property. By default, it has a __proto__ property, whose value refers to the constructor’s prototype object. Properties added or modified on the prototype object are shared across all instantiated objects.

When an attribute is accessed from an instantiated object, it is first looked for inside the object or, if it cannot be found, to it__proto__If you still can’t find it, continue to the prototype__proto__Point to the parent prototype until it finds orObject.prototypeSo far, the chain process is zeroPrototype chain.

Thirty-one. Implement oneEventBus

Simple implementation

class myEventBus {
  constructor(props) {
    this.events = {}
  }
  on (event, fn) {
    const events = this.events events[event] ? events[event].push(fn) : (events[event] = [fn]) } emit (event, ... res) {this.events[event] && this.events[event].forEach(fn= > {
      return fn.apply(this, res)
    })
  }
  remove (event, fn) {
    if (this.events[event]) {
      delete this.events[event]
    }
  }
}
Copy the code

32,jsGarbage collection (GC)

1.V8Memory limit

  • 64-bit systems can use 1.4 GIGABytes of memory
  • 32-bit systems can use 0.7 GB of memory

2,V8Memory management

  • JSObjects are all passedV8To allocate and manage memory
  • process.memoryUsage()Returns an object containing theNodeMemory usage of the process

3. Structure diagram of memory occupancy

  • Var a = {name: "yuhua"};This code does the following:
    • Place this code in the code areaCode Segment
    • The variableaPut into “stack” (Stack) : local variable, pointer
    • will{name: "yuhua"}In the”HeapTotal(heap) : object, closure”
  • Note: The base data types are in the stack, and the reference types are in the heap

4. Why limit memory size

  • becauseV8As a result of the garbage collection working principle, it takes more than 1s to complete a garbage collection of 1.4GB memory
  • The garbage collection period (pause time) becomesStop The WorldDuring this time, application performance and responsiveness can degrade

5,V8Garbage collection mechanism

  • V8Is based on generational garbage collection
  • Different generation garbage collection mechanisms are also different, using different algorithms
  • According to the time of inventory is divided into the new generation and old generation

6, generational

  • The younger ones are the new onesFromRegional andToArea Consists of two areas
  • On 64-bit systems, the new generation has 32 megabytes of memory,FromRegional andToEach area occupies 16M
  • On 32-bit systems, the new generation has 16 megabytes of memory,FromRegional andToEach area occupies 8M
  • The older are the older generation, and by default:
    • Old generation memory on 64-bit system is 1400 MB
    • The old generation memory on a 32-bit system is 700 MB

7, the new generation of adoptionScavengealgorithm

Scavenge is an algorithm used for the generation of the Scavenge avenge.

The Cenozoic scanning is a breadth-first scanning strategy

It divides memory into from and to Spaces. On each GC, live objects from the FROM space are copied to the TO space. Then the two spatial roles are reversed (also known as inverted).

This algorithm sacrifices space for time, so it is suitable for the new generation, because its objects have a short life cycle.

1. The process

  • The new generation area is divided into two sections, each 16M, one used and one idle
  • When garbage collection begins, it is checkedFROMThe live object in the zone, if still alive, is copied toTOSpace, empty (free) after all living objects have been copiedFROMarea
  • And then the FROM and To fields are switched

Characteristics of 2.

  • The Cenozoic scanning is a breadth-first scanning strategy
  • The Cenozoic era has little space and few living objects
  • When an object manager’s multiple garbage collections survive, objects with poor life cycles are moved to the old cords, a process known as promotion or promotion
  • Those that have gone through more than five collections still exist
  • TOMore than 25% of space usage, or very large objects
  • The browsermemoryCan be tapped to see if variables are garbage collected
  • Set toundefinednullCan subtract 1 from the reference count

8, old generation adoptedMark-SweepMark-Compact

1. The basic

  • Old-generation garbage collection strategies fall into two categories
    • mark-sweepMark clear
      • Mark living objects, although it is clear that there are no marked objects in the mark phase, and only clean up dead objects

      Problems that can occur: Memory is discontinuous after clearing, and fragmented memory cannot be allocated

    • mark-compactTag to sort out
      • Dead marks will defragment the object, move it to the left if it is alive, and then clean up memory outside the boundary (dead objects)
  • Old age space is large, most of them are living objects,GCIt takes a long time
  • inGCAnd I can’t listen to it,STOP-THE-WORLD
  • V8There is an optimization, incremental processing, where one big pause is replaced by many small pausesINCREMENT-GC
  • The idea is to break the big pause into smaller pauses, with the application running for a short period of time, so that the garbage collection and the application alternate, reducing the pause time to about 1/6

Process of 2.

Let’s say I have 10 sizes of memory, and I take up 6 of them,

1)Mark-SweepSchema garbage collection:
  • Then each object will be marked:
A, b, C, d, E, f Empty empty // Mark each of the above objects with upper case for alive and lower case for dead // There is A problem that the memory fragment cannot be used because the lower case memory is not used with the empty memory behind itCopy the code
  • The lower case (dead) will be eliminated, and only the upper case (live) will remain, resulting in the problem of memory fragmentation being unavailable
2)Mark-CompactSchema garbage collection
  • Move the live left
A C E B D F empty empty emptyCopy the code
  • And then reclaim the dead area
A C E empty empty empty empty emptyCopy the code

9. Comparison of the three algorithms

Recovery algorithm Mark-Sweep Mark-Compact Scavenge
speed medium The slowest The fastest
The space overhead less less Double space (no debris)
Whether to move objects no is is
  • V8Old generation mainly usedMark-SweepBecause theMark-CompactObjects need to be moved and execution is slow. I only use it when I run out of spaceMark-Compact

33. Design Patterns

1. Design Principles:

1. Single responsibility principle (SRP)

An object or method does only one thing.

2. Least Knowledge Principle (LKP)

Interactions between objects should be minimized.

3. Open-closure principle (OCP)

Software entities (classes, modules, functions), etc., should be extensible but not modifiable

2. Strategy mode

The strategy pattern defines a set of algorithms, encapsulates each algorithm, and makes them interchangeable. The policy pattern lets the algorithm change independently of the customers that use it. Advantages:

  • The policy pattern uses techniques and ideas such as composition and delegation to avoid many if conditional statements
  • The policy pattern provides an open-closed principle that makes code easier to understand and expand

Example:

  1. Performance rating and salary are calculated as bonus
  2. Form validation usually involves validation of multiple fields

Caching proxy mode

The cache proxy can provide temporary storage for some expensive operation results. In the next operation, if the parameter passed in is the same as the previous one, it can directly return the stored operation results, providing efficiency and saving overhead.

Caching proxy, which caches previously used values and then uses them for future use.

4. Factory mode

The factory pattern is one of the most common design patterns used to create objects. Instead of exposing the concrete logic that creates the object, we will encapsulate the logic in a function that can then be thought of as a factory. According to the degree of abstraction, factory patterns can be divided into simple factories, factory methods and abstract factories.

The advantage of a simple factory is that you only need one correct parameter to get the object you need, without knowing the details of its creation. Simple factories can only be used when a small number of objects are being created and the creation logic of objects is not complex.

The factory method pattern is intended to defer the actual creation of objects to subclasses. The factory method pattern is to break up the big factory into smaller factories, and each time a new product is added, the small factory produces it, and the big factory takes charge.

The abstract factory pattern does not generate instances directly, but is used to create clusters of product classes.

5. Singleton mode

Ensure that a class has only one instance and provide a global access point to access it.

Ensures that there is only one instance

  • Since there is only one instance, you save system resources, and remember that creating and destroying also wastes memory resources
  • Multiple resources, such as database connections, are avoided
  • Resource sharing

Front-end application scenarios:

  • The browserwindowObject. inJavaScriptIn development, singleton implementations are often used for objects that require only one.
  • Mask, landing window, etc.

6. Proxy mode

Provides a proxy or placeholder for an object to control access to it.

There are three proxy modes: protected proxy, virtual proxy, and cache proxy

Iterator pattern

The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing the internal representation of the object.

The map forEach of arrays in JS already has iterators built in

8. Publish-subscriber model

Also known as the observer pattern, it defines a one-to-many dependency between objects in which all dependent objects are notified when an object’s state changes.

Events in JS are an implementation of the classic publish-subscribe pattern

Command mode

Programs are designed in such a loosely-coupled way that request senders and request receivers decouple from each other. A command is an instruction that does something specific

Functions & self-executing functions

1. Features of self-executing functions

  1. Function expressions differ from function declarations in that function names are only valid inside the function, and the binding is a constant binding.
  2. Assign to a constant atstrictAn error is reported in mode, nostrictSilent failed in mode.
  3. IIFEFunctions in are function expressions, not function declarations.

2. Function types

  1. Function declaration
  2. Functional expression
  3. Function constructor created

1. Function declaration (FD)

  1. It has a specific name
  2. Position in the source: either at the program level (Program level), or in the body of another function (FunctionBody)
  3. Created in the enter context phase
  4. Influence variable object
  5. Declare as follows
function funName () {}
Copy the code

2. Function expression (FE)

  1. Must appear at the position of the expression in the source code
  2. There are optional names
  3. Variable objects are not affected
  4. Created during code execution
// Function expression
var foo = function () {} // The anonymous function expression is assigned to the variable foo
var foo2 = function _foo2() {} // External FE is accessed through the variable "foo" -- foo(), while inside functions (such as recursive calls) it is possible to use the name "_foo".
// Only expressions can be inside parentheses (grouping operators)
(function foo() {});
// Can only be expressions in array initializers
[function bar() {}];
// Commas can only operate on expressions
1.function baz() {};
// !
!function() {} (); (function foo() {}) ()// self-executing function IIFE
(function () {}) ()// IIFT
var foo = {
  bar: function (x) {
    return x % 2! =0 ? 'yes' : 'no'; } (1)}; foo.bar// 'yes'
Copy the code

3. The function created by the function constructor

We distinguish it from FD and FE. The main feature is that the [[Scope]] property of this function contains only global objects

var x = 10;
function foo() {
  var x = 20;
  var y = 30;
  var bar = new Function('alert(x); alert(y); ');
  bar(); // 10, "y" is undefined
}
Copy the code

3, how to create a function that does not need () to execute

  1. Create an object
  2. Object where expressions define self-executing functions
var foo = {
  bar: function (x) {
    return x % 2! =0 ? 'yes' : 'no'; } (1)}; foo.bar// 'yes'
Copy the code

4. Why do some need to be added(a)Some can be left out, right?

The grouping operator parentheses are required when the function is not in the expression position — that is, to manually convert the function to FE.

If the parser knows it is dealing with FE, there is no need to use parentheses.

5. Named function expressions

An important feature occurs when the function expression FE has a name (called named function expression, abbreviated NFE).

We know from the definition (as we saw from the example above) that function expressions do not affect variable objects in a context (that means it is impossible to call a function by name either before or after it is declared). However, FE can call itself by name in recursive calls.

(function foo(bar) {
  if (bar) {
    return;
  }
  foo(true); // "foo" is available}) ();Copy the code

Where is “foo” stored? In foo’s live object? No, because there is no definition of any “foo” in foo. Create foo in the parent variable object of the context? Not really, because by definition — FE doesn’t affect VO (variable object) — we can actually see that when foo is called externally. So where is it?

When the interpreter encounters a named FE during code execution, it creates the auxiliary specific object and adds it to the very front of the current scope chain before FE is created. It then creates FE, at which point (as we learned in Chapter 4 Scope Chains) the function gets the [[Scope]] attribute — the Scope chain that created this function context). After that, the name FE is added to the specific object as a unique attribute; The value of this attribute is referenced to FE. The last step is to remove that particular object from the parent scope chain.

6. Self-executing function examples

/ / a
+function foo(){
foo=10;// My problem code
    console.log(foo);// The method itself} ();console.log(typeof foo);//undefined to check for global contamination

/ / two cases
var b = 10;
(function b() {
   // The internal scope is set to 20 if there is a declaration of the existing variable b. Function b(){} function b(){}
   // The IIFE function cannot be assigned (internal mechanism, like const const), so it is invalid.
  // The internal mechanism of IIFE in JS engine, stack storage of IIFE, etc.
    b = 20;
    console.log(b); // [Function b]
    console.log(window.b); // 10, not 20}) ();// Strict mode will report an error
var b = 10;
(function b() {
  'use strict'
  b = 20;
  console.log(b)
})() // "Uncaught TypeError: Assignment to constant variable."

// A normal function
function a () {
    a = 1
    console.log(a)
}
a() / / 1
a() // a is not a function
Copy the code

35,XSSAttacks andCSRFattack

1.XSSattack

1. The concept

XSS (Cross Site Scripting) : Cross-domain Scripting attacks

Principle 2.

You don’t need to do any login authentication, it will inject scripts (js, HMTL code blocks, etc.) into your page through legitimate actions (such as typing in the URL, in the comment box).

3. To prevent

  1. Coding; Encode user input.
  2. Filtering; Removes attributes related to user input and events. (filterscript,style,iframeSuch as node)
  3. Correction; useDOM ParseConvert, correct unpairedDOMThe label.
  4. HttpOnly.

Classification of 4.

  • Reflective (non-persistent) : Click the link to execute the script
  • Storage (persistent) : Malicious input saves the database, other users access, execute scripts
  • Based on theDOM: Malicious modificationDOMStructure, based on the client

2,CSRFattack

1. The concept

Cross-site Request Forgery (SRF) : Cross-site request forgery.

Principle 2.

  1. Log on to trusted sitesAAnd generate it locallyCookie. (If the user is not logged in to the siteA, so the websiteBAt the time of induction, request the siteAapiInterface, will prompt you to log in).
  2. Without logoutAIn the case of visiting dangerous websitesB(Actually using the websiteA“).

3. To prevent

  1. tokenValidation;
  2. Hide the token; thetokenHidden in thehttpThe request ofheadIn the.
  3. refererValidation; Verify the page source.

3. The difference between the two

  1. CSRF: You need to log in to the website firstATo obtaincookie.XSS: No login is required.
  2. CSRF: Use the websiteAThe vulnerability itself, to request the siteAapi.XSS: Is to the websiteAinjectionJSCode, and then executeJSTo tamper with the websiteAThe content of the.

36,inputInput box input is the request back-end interface, after frequent requests how to determine the return value of the last interface?

1. Back end returns the request value (simplest)

When the front end requests the interface, it will pass the value in the input box to the back end. At this time, when the back end returns the interface data, it will return the value passed in by the front end. The page rendering only needs to make judgment.

2. Terminate the last request

Abort the previous request when requested again:

  1. ajax:abort()
  2. axios: CancelToken
  3. fetch:AbortController

This is the way Baidu cancels requests

Js:ss1.bdstatic.com/5eN1bjq8AAU…

3. Define a globalID, the interface requests the value, then requests the interface closure to save the value, and returns the value to determine both.

In this way, the front end stores the corresponding value information for judgment processing without the return value of the back end

implementation

let id = 1
function ajax() {
  ++id
  console.log(id)
  function getData () {
    const newId = id
    const time = Math.random() * 5000 | 0 // Define a random value
    console.log('time', time)
    setTimeout(() = > {
      console.log('id newId', id, newId)
      if (id === newId) { // Do some data processing here
        console.log('this is true-->', id)
      }
    }, time)
  }
  getData()
}
// click the start function frequently
document.getElementById('ajaxbtn').onclick = function () {
  ajax()
}
Copy the code

37,rem

1, define,

Rem (font size of the root Element) is a unit of font size relative to the root element. 1rem is equal to the font size of the root element HTM, that is, only the font size of the root element needs to be set. When the rem unit is used for other elements, the corresponding percentage can be set.

2, how to achieve

Rem (multiple) => width/(HTML font-size) => width = (HTML font-size) * rem(multiple)Copy the code

As long as the font size of THE HTML changes, the width will automatically change, so REM dynamically sets the font size of the HTML to change the width, in order to achieve the purpose of self-adaptive web page size

Rem (multiple) = width/(HTML font size)

Rem (multiple) = imgWidth (imgWidth)/font size(defalutSize) REM (multiple) = the actual width of the page (screenWidth)/font size(x) that you need to set dynamically , the formula for setting the FONT size of HTML is:

<script type="text/javascript">
  (function(w,d) {
  function setSize() {
    var screenWidth = d.documentElement.clientWidth;
    var currentFontSize = screenWidth * 100 / 750;
    d.documentElement.style.fontSize = currentFontSize + 'px';
  }
  w.addEventListener('resize',setSize);
  w.addEventListener('pageShow',setSize)
  w.addEventListener('DOMContentLoaded',setSize)
})(window.document)
</script>
Copy the code
function setHtmlSize(){
  var pageWidth = window.innerWidth;
  if(typeofpageWidth ! ="number") {if(document.compatMode == "number"){ 
      pageWidth = document.documentElement.clientWidth;
    }else{ 
      pageWidth = document.body.clientWidth; }}var fontSize = (window.innerWidth * 100) / 750;
  if(fontSize<40){
    fontSize = 40;
  }
  // Determine the root node size based on the screen size
  document.getElementsByTagName('html') [0].style.fontSize = fontSize + 'px';
}
function resize(){
  setHtmlSize();
}
if (window.attachEvent) { 
  window.attachEvent("resize", resize); 
} else if (window.addEventListener) { 
  window.addEventListener("resize", resize, false);   
}
setHtmlSize();
Copy the code

3,750In terms of width,1rem = 100px.iphone6/7/8 plusSet in theWidth: 6.5 remWhat is the width of the element?

The width in PLUS is 414 so the width is 414/750 * 6.5 * 100 0.32 REM is 414/750 * 0.32 * 100

Thirty-eight,dns-prefetch,prefetch,preload,defer,async

1.dns-prefetch

Converting a domain name to an IP is a time-consuming process, and dnS-Prefetch lets your browser do it for you when it’s idle. In particular, large websites use multiple domain names, which requires DNS prefetch.

// From baidu home page<link rel="dns-prefetch" href="//m.baidu.com">
Copy the code

2,prefetch

Prefetch is generally used to preload resources that may be used. It is a judgment of user behavior. The browser will load prefetch resources when it is idle.

<link rel="prefetch" href="http://www.example.com/">
Copy the code

3,preload

Unlike Prefetch, a prefecture-oriented th usually loads resources for a page that may be used next, while Preload is a resource for a script, style, font, image or other resources that are used to load the current page. So instead of loading at idle, preload has a higher priority and consumes HTTP requests.

<link rel='preload' href='style.css' as="style" onload="console.log('style loaded')"
Copy the code

asValue including

  • script
  • style
  • image
  • media
  • document onloadMethod is a callback function after the resource has been loaded

4,deferasync

//defer
<script defer src="script.js"></script>
//async
<script async src="script.js"></script>
Copy the code

Both defer and Async load resources asynchronously (in parallel). The difference is that async executes immediately after loading, while defer does not execute until all elements are parsed, that is, before the DOMContentLoaded event is triggered. Since async loads resources after they are loaded and executed, it does not guarantee order, and defer executes the scripts in order.

39. Browser rendering process

1. The browser rendering process is as follows

  • parsingHTMLTo generate theDOM
  • parsingCSSTo generate theCSSOM
  • willDOMTrees andCSSOMTree combination to generate render tree (Render Tree)
  • Layout(Backflow) : Based on the generated render tree, backflow (Layout), get the geometric information of the node (position, size)
  • Painting(Redraw) : Obtain the absolute pixels of nodes based on the rendered tree and geometry information obtained by backflow
  • Display: sends the pixel toGPU, displayed on the page. (There are many other aspects of this step, such as the meeting inGPUCombine multiple composition layers into one layer and display them on a page. whilecss3Hardware acceleration works by creating a composition layer.

2. When to trigger backflow and redraw

1. Return

  • Add or remove visibleDOMThe element
  • The position of the element changes
  • The size of the element changes (including margins, inner borders, border size, height, width, etc.)
  • Content changes, such as text changes or an image being replaced by another image of a different size.
  • When the page is first rendered (which is inevitable)
  • Browser window size changes (because backflow calculates element position and size based on viewport size)

2. Redrawn

  • Backflow must trigger redraw
  • When an element style change in a page does not affect its position in the document flow (for example:color,background-color,visibilityAnd so on), the browser assigns the new style to the element and redraws it, a process called redraw.

3. Avoid triggering backflow and redraw

1. css

  • Avoid the use oftableLayout.
  • As far as possible inDOMThe end of the tree changesclass.
  • Avoid setting multiple inline styles.
  • Apply the animation effect topositionProperties forabsolutefixedOn the elements of
  • Avoid the use ofCSSExpressions (e.g.calc())
  • CSS3Hardware acceleration (GPUAcceleration)
    • transform
    • opacity
    • filters
    • Will-change

2. JavaScript

  • Avoid frequent manipulation of styles; it is best to rewrite them all at oncestyleProperty, or define the style list asclassAnd change it onceclassProperties, modifystylecssTextAttributes or modifies elementsclassNameValue.
  • Avoid frequent operationsDOM, create adocumentFragmentApply all of them to itDOMAction, and finally add it to the document
  • You can also set the element firstdisplay: none, and then display it after the operation. Because in thedisplayProperties fornoneOn the element ofDOMThe operation does not cause backflow and redraw
  • Avoid frequently reading properties that cause backflow/redraw, and if you do need to use them more than once, cache them in a variable
  • Use absolute positioning on elements with complex animations to keep them out of the document stream, which would otherwise cause frequent backflow of parent elements and subsequent elements.
  • usecss3Hardware acceleration, you can maketransform,opacity,filtersThese animations do not cause backflow redraw. But other properties of the animation, for examplebackground-colorThis will still cause backflow redraw, but it will still improve the performance of these animations.

4. Hardware acceleration principle

When the browser receives the page document, it parses the markup language in the document into a DOM tree. The DOM tree and CSS are combined to form a rendering tree for the browser to build the page. The rendering tree contains a large number of rendering elements. Each rendering element will be assigned to a layer, and each layer will be loaded to the GPU to form a rendering texture. The transform of layers in the GPU will not trigger repaint. Ultimately the transform layers are processed by a separate synthesizer process.

1. When will the browser create a separate composite layer?

  • 3DorCSS transform
  • <video><canvas>The label
  • CSS filters
  • Element overrides, such as usingz-indexattribute

The difference between 3D and 2D Transform is that the browser creates a separate composite layer for the 3D animation before rendering the page, while it creates a composite layer for the 2D animation during runtime. When the animation starts, a new composite layer is generated and loaded as a texture for the GPU to initialize the Repaint. The execution of the entire animation is then manipulated by the GPU’s compositor. Finally, when the animation ends, repaint is used again to remove the composite layer.

2. Problems with hardware acceleration

  • Memory. ifGPULoading a lot of textures can easily lead to content problems, especially on mobile browsers, so it’s important to remember not to use hardware acceleration on every element of the page.
  • useGPURendering affects the anti-aliasing effect of a font. This is becauseGPUCPUThere are different rendering mechanisms. Even if the hardware acceleration eventually stops, the text will still appear blurry during the animation.

Forty,JSBridge

1. What isJSBridge

JSBridge is a JS implemented Bridge that connects Native and H5 at both ends of the Bridge. It conveniently allows Native to call JS in APP, and JS calls Native, which is a two-way communication channel. JSBridge mainly provides the ability of JS to call Native code to realize Native functions such as viewing local photo albums, opening camera, fingerprint payment, etc.

2,H5nativeThe difference between

name H5 Native
The stability of Call system browser kernel, poor stability Use native kernel, more stable
flexibility Version iteration fast, flexible online Iterations are slow, app store reviews are required, and the launch speed is limited
Affected by network speed larger smaller
fluency Sometimes the load is slow, giving the user the feeling of “lag” Fast loading speed, more smooth
The user experience Features are limited by browsers and the experience is sometimes poor The original systemapiRich, can realize more functions, better experience
portability Compatible across platforms and systems, such asPCAnd mobile,iOSAndroid Low portability foriOSAndroidTwo sets of code need to be maintained
# # # 3,JSBridgeThe purpose of the
JSBridgeAs in its name,Bridge“Means the same as, yesNativeAnd theNativeThe bridge between its core is builtNativeAnd theNativeA channel for message communication between, and for two-way communication.
2. A channel of two-way communication:
  • JSNativeSend messages: invoke related functions and notificationsNativeThe currentJSRelated state, etc.
  • NativeJSSend messages: backtrace call results, message push, notificationJSThe currentNativeState, etc.

4,JSBridgeprocess

H5 -> somehow triggers a URL -> Native captures the URL for analysis -> Native does the processing -> Native calls H5’s JSBridge object to pass the callback.

The implementation process

  • Step 1: Design oneNativeJSInteractive global bridge objects
  • The second step:JSHow to callNative
  • Step 3:NativeHow to learnapiIs called
  • Step 4: Analyzeurl-Format of arguments and callbacks
  • Step 5:NativeHow to callJS
  • Step 6:H5apiMethod registration and format

5,JSBridgeImplementation principle of

  • JavaScriptcallNativeInjection is recommendedAPIThe way (iOS6Ignore,The Android 4.2Use the followingWebViewClientonJsPromptWay).
  • NativecallJavaScriptThe spliced one is executed directlyJavaScriptCode.

React Native iOS example: JavaScript running in JSCore can actually use the injection API to implement JavaScript calling Native functions in the same way as above. React Native is not designed for JavaScript to call object-C directly. Instead, it is designed to be consistent with the event response mechanism in Native development. It is designed to trigger the call with a return value only when object-C calls JavaScript. The principle is basically the same, but the implementation is different.

1. NativeJS

1) android

Calling NATIVE JS is easy, just follow the rule: “javascript: method name (‘ parameter, need to be converted to string ‘)”.

mWebView.evaluateJavascript("Javascript: method name (' parameter, need to be converted to string ')".new ValueCallback() {
        @Override public void onReceiveValue(String value) { // the value is the return value of the corresponding JS method}
});
Copy the code
2)IOS

Native Html binding through stringByEvaluatingJavaScriptFromString calls on the window function.

2. JSNative

1) android

Native adds exposed JS bridge objects through addJavascriptInterface, and then declares corresponding API methods inside this object.

private Object getJSBridge(a){  
    Object insertObj = new Object(){ @JavascriptInterface public String foo(a){ return "foo";  
        } @JavascriptInterface public String foo2(final String param){ return "foo2:"+ param; }};return insertObj;  
}
Copy the code
2)IOS

Native uses the official JavaScriptCore library (iOS7 +) to bind the API to the JSContext (and then javascript in Html can be called by default through window.top.*).

6,JSBridgeInterface implementation

JSBridge interface has two main functions: calling Native (sending messages to Native) and receiving calls to Native (receiving messages to Native).

1. Messages are one-way, so callNativeWhen the functionCallbackHow do you do that?

JSBridge’s Callback is the RPC framework’s Callback mechanism. Of course, it can also be explained by the simpler JSONP mechanism:

When a JSONP request is sent, the URL parameter will have a callback parameter, whose value is unique to the current page, and the callback function will be stored on the window with this parameter value as key. Then, the server will return the script with this parameter value as a handle to call the corresponding callback function.

The unique identification of the callback parameter is the key to the callback logic. In this way, we can implement JSBridge by following this logic: identify and store the callback function with an increment unique ID, and pass this ID as a parameter to Native, which in turn uses this ID as a traceback identifier. In this way, the Callback Callback logic can be implemented.

(function () {
    var id = 0,
        callbacks = {},
        registerFuncs = {};
    window.JSBridge = {
        / / call Native
        invoke: function(bridgeName, callback, data) {
            // Determine the environment to get different NativeBridges
            var thisId = id ++; // Get the unique ID
            callbacks[thisId] = callback; / / store the Callback
            nativeBridge.postMessage({
                bridgeName: bridgeName,
                data: data || {},
                callbackId: thisId // Pass to Native
            });
        },
        receiveMessage: function(msg) {
            var bridgeName = msg.bridgeName,
                data = msg.data || {},
                callbackId = msg.callbackId, // Native returns the callbackId intact
                responstId = msg.responstId;
            // Specific logic
            // bridgeName and callbackId do not exist together
            if (callbackId) {
                if (callbacks[callbackId]) { // Find the corresponding handle
                    callbacks[callbackId](msg.data); // Perform the call
                }
            } elseif (bridgeName) {
                if (registerFuncs[bridgeName]) { // Find the handle by bridgeName
                    var ret = {},
                        flag = false;
                    registerFuncs[bridgeName].forEach(function(callback) = >{
                        callback(data, function(r) {
                            flag = true;
                            ret = Object.assign(ret, r);
                        });
                    });
                    if (flag) {
                        nativeBridge.postMessage({ / / callback Native
                            responstId: responstId,
                            ret: ret }); }}}},register: function(bridgeName, callback) {
            if(! registerFuncs[bridgeName]) { registerFuncs[bridgeName] = []; } registerFuncs[bridgeName].push(callback);// Store callback
        }
    };
})();
Copy the code

7,JSBridgeHow to reference

By 1.NativeEnd injection

The injection method is similar to Native JavaScript, which directly executes all the code of the bridge.

Advantages: The bridge version is easy to be consistent with Native, Native end does not need to be compatible with different versions of JSBridge; At the same time,

Disadvantages: The injection timing is uncertain, and the mechanism of retry after injection failure needs to be implemented to ensure the success rate of injection. At the same time, the JavaScript side needs to give priority to the interface invocation.

By 2.JavaScriptThe reference

Executes directly with JavaScript.

Advantages: JavaScript side can determine the existence of JSBridge, directly call; Disadvantages: If the Bridge implementation changes, JSBridge needs to be compatible with multiple versions of Native Bridge or Native Bridge needs to be compatible with multiple versions of JSBridge.

41,web worker

1. What isweb worker? What are the benefits? What are the problems?

Web workers create a multithreaded environment for JavaScript, allowing the main thread to create Worker threads and assign some tasks to the latter to run. While the main thread is running, the Worker thread is running in the background without interfering with each other. Wait until the Worker thread completes the calculation and returns the result to the main thread.

benefits:

The benefit is that when computationally intensive or high-latency tasks are taken on by Worker threads, the main thread (which is usually responsible for UI interactions) will flow smoothly and not be blocked or slowed down.

Question:

Once a Worker thread is created, it is always running and is not interrupted by activity on the main thread, such as a user clicking a button or submitting a form. This facilitates communication that responds to the main thread at any time. However, this also causes the Worker to consume resources, so it should not be overused and should be closed once it is used.

2, use,web workerWhat are the restrictions?

1. Homology restriction

The script file assigned to worker must be of the same origin as the main thread script file.

2. DOMlimit

The worker thread cannot read the DOM object of the page where the main thread is located. Instead of using document, window, parent objects, it can use navigator and Location objects.

3. Communication restrictions

The worker thread and the main thread are no longer in the same context and cannot communicate directly, which must be done through messages.

4. Script limitations

Worker threads cannot execute alert and confirm methods, but can make Ajax requests.

5. File restrictions

Worker threads cannot read local files, cannot open file systems, and must load scripts from the network that cannot be file:// files.

3,workerHow do threads listen for messages on the main thread? How is the message sent?workerHow is the thread closed?

Worker threads need to have a listener function inside that listens for message events.

/ / to monitor
self.addEventListener('message'.function (e) {
  // Send a message
  self.postMessage('You said: ' + e.data);
}, false);
Copy the code

Shut downworkerthread

1) Main thread is closedworkerthread

worker.terminate()

2)workerThread closed

self.close()

4,workerHow do threads load other scripts?

importScript('scripts.js')
importScript('scripts1.js'.'scripts2.js')
Copy the code

5, the main thread andworkerThe threadAPI

The main thread workerthread
Worker.onerror: specifyerrorA listener function for the event self.name:WorkerThe name of the
Worker.onmessage: specifymessageA listener function for the event self.onmessage: specifymessageA listener function for the event
Worker.onmessageerror: specifymessageerrorA listener function for the event self.onmessageerror: specifymessageerrorA listener function for the event
Worker.postMessage()To:WorkerThread sending message self.close()Closed:Workerthread
Worker.terminate(): Immediate terminationWorkerthread self.postMessage(): To produce thisWorkerThread sending message
self.importScripts()Loading:JSThe script

42,webSocket

1. WhywebSocket? What are the characteristics?

1. Advantages:

  1. Support two-way communication, more real-time;
  2. Better binary support;
  3. wsWhen data is exchanged between the client and the server, the packet header is smaller and the cost is better controlled.
  4. Support outreach.

2. Features:

  1. Based on theTCPProtocol, the server side implementation is easier.
  2. withHTTPThe protocol has good compatibility. The default ports are also 80 and 443, and are used for the handshake phaseHTTPProtocol, so handshake is not easy to shield, can pass through a variety ofHTTPProxy server.
  3. The data format is relatively light, with low performance overhead and high communication efficiency.
  4. You can send text or binary data.
  5. There are no same-origin restrictions, and clients can communicate with any server.
  6. The protocol identifier isws(If encrypted, otherwisewss), the server url isURL.

2,webSocketLink status of?

  • 0 (WebSocket.CONNECTING)Linking now
  • 1 (WebSocket.OPEN)Already linked and able to communicate
  • 2 (WebSocket.CLOSING)Connection closing
  • 3 (WebSocket.CLOSED)Connection closed or failed