1. Closures

What is a closure? A closure is a function that has access to variables in the scope of other functions. In js, variables are divided into global and local variables, local variables is belong to the scope of the function scope, the function after scope is destroyed, the memory will be recycled, but because of the closure is based on the function of internal function, because of its access to superior scope, even superior functions performed, the scope is not destroyed, At this point, the child function, the closure, has access to the variables in the parent scope, and the values in the scope are not destroyed even after the parent function has finished executing.

What do closures solve? In essence, a closure is a bridge between the inside and outside of a function. Because closures can cache the parent scope, variables inside the function can be accessed outside the function.

Closure application scenarios Ajax request successful callback an event-bound callback method setTimeout delay callback a function internally returns another anonymous function

Disadvantages: Using too many closures consumes a lot of memory, resulting in memory leakage

2. Prototypes and prototype chains

You don’t have to read this picture

(1). All reference types have a __proto__ (implicit stereotype) attribute whose value is an ordinary object (2). In addition to having a __proto__ attribute, all functions have a prototype attribute whose value is a generic object (3). All reference types have a constructor property that (which is a pointer) points to its constructor (4.). The __proto__ attribute of all reference types points to the prototype of its constructor

When an object calls a property/method that doesn’t exist on its own, it first looks for its _proto_, the prototype of its constructor. If not, the constructor looks in the prototype of the function whose prototype _proto_ points to, and finally points to null. Such upward-looking relationships form a chain structure called a prototype chain.

In-depth understanding of JS prototypes and prototype chains

Understand constructor, Prototype, __proto__, and prototype chains in your own way

Understand JS prototypes and prototype chains with examples

ES5 inheritance and ES6 inheritance

ES5: Combinatorial inheritance, which creates an instance object of a subclass and then adds the parent class’s methods to this via the call method, via the mechanism of stereotypes and constructors

Example:

Function Parent() {this.name = 'Parent' this.age = 50 this.sex = 'male'} // Add a method to the Parent's prototype Function () {console.log(' go to play mag ')} // Define a subclass function Child(name) {this.name = name // Parent.call(this)} parent.call (this)} parent.call (this)} Lost the constructor of the Child. The prototype. The constructor = ChildCopy the code

ES6: We first create an instance object of the parent class, this (so we must call the super() method of the parent class first and then modify this using the constructor of the subclasses). We define the classes using the class keyword. We extend the classes using the extends keyword. Because a subclass doesn’t have its own this object, it inherits its parent’s this object and processes it. If you don’t call super, the subclass doesn’t get this.

Example:

Class Parent {constructor(name, constructor) Sex) {this.name = name this.sex = sex} play() {console.log(this.name + 'play mahjong super garbage ')} speak() {console.log(' sex is: '+ this.sex)}} let father = new Parent(' old high ',' male ') father. Play () father Constructor (sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) {constructor(sex) { Sex)}} let son = new Child('小高', '女') son.play() son.speak()Copy the code

4. Native AJAX request steps

Five steps to use: (1). Create an XMLHTTPRequest object (2). Use the open method to set the interaction information with the server (3). Set the data to be sent and start the interaction with the server (4). Register event (5). Update the interface

Get request:

Let XHR = new XMLHttpRequest() Xhr.open ('get', '/baidu.com? Username =1') // Xhr.send () // Step 4: Register event onReadyStatechange, Xhr.onreadystatechange = function () {if (xhr.readyState === 4 &&xhr.status === = 200) {// If this step is reached, the data is returned and the requested page is present console.log(xhr.responsetext)}}Copy the code

POST request:

// Step 1: Let XHR = new XMLHttpRequest() // Post requests must include a request header, Xhr. setRequestHeader(' content-type ', 'application/x-www-form-urlencoded') // Xhr.open ('post', '/baidu.com') // Xhr. send('username=1&password=123') // step 4: Register event onReadyStatechange, Xhr.onreadystatechange = function () {if (xhr.readyState === 4 &&xhr.status === = 200) {// If this step is reached, the data is returned and the requested page is present console.log(xhr.responsetext)}}Copy the code

5. About event delegation

What is event delegate? Event delegate is also called event broker, which uses event bubble to manage all events of a certain type by specifying only one event handler.

The functions of event delegate (1). Improve performance: each function will occupy memory space, just add a time handler to proxy all events, occupying less memory space; (2). Dynamic listener: using event delegate, dynamically added elements can be automatically bound, that is, the newly added node can have the same event as other elements without active addition.

Let’s take a look at the implementation of multiple events that need to be bound without event delegate:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> <li Class = "item" > button < / li > < li class = "item" > button < / li > < li class = "item" > button < / li > < li class = "item" > button < / li > < / ul > < / body > < script > window.onload = function () { let lis = document.getElementsByClassName('item') for (let i = 0; i < lis.length; I++) {lis [I] onclick = function () {the console. The log (' force of the point I ')}}} < / script > < / HTML >Copy the code

Instead of using event delegates, you have to iterate over every LI element and bind a click event to every Li element, which is very memory intensive, and if you have 100, 1000 Li elements, it can have a huge impact on performance.

So how does this work with event delegates?

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul id="wrap"> <li Class = "item" > button < / li > < li class = "item" > button < / li > < li class = "item" > button < / li > < li class = "item" > button < / li > < / ul > < / body > < script > Onload = function () {let ul = document.getelementById ('wrap') ul.onclick = function () Ev | | window. Click the event / / if the element calssName for item if (e. arget. ClassName = = = 'item') {the console. The log (' force of the point I ')}}} < / script > </html>Copy the code

In this way, with the event delegate, you only need to bind a click event to ul, the parent element of the Li element, and through the event bubble mechanism, you can achieve the click effect of Li. Add li elements dynamically through JS, and you can also bind click events.

6. Null is not an object but why typeof NULL === object

In js, if the first three bits of the binary are all 0, then the object type will be judged as object. Therefore, typeof NULL === objCET.

7. About deep and shallow copies

Shallow copy: A pointer to an object is copied, but not the object itself. The old and new objects still share the same memory

Implementation:

Method 1: Assign directly with =

let obj1 = {a: 1}
let obj2 = obj1
Copy the code

Method 2: object.assign Note: (1). It does not copy the Object’s inherited properties (2). It does not copy the object’s non-enumerable properties (3). It can copy properties of type Symbol

let obj1 = {a: 1}
let obj2 = {}
Object.assign(obj2, obj1)
Copy the code

Method 3: The for in loop traverses only the first layer

function shallowObj(obj) { if (typeof obj === 'object' && obj ! == null) { let result = Array.isArray(obj) ? [] : {} for (let key in obj) { if (Object.hasOwnProperty(key)) { result[key] = obj[key] } } return result } else return obj }  let obj1 = { a: 1, b: { c: 2 } } let obj2 = shallowObj(obj1) obj1.b.c = 3 console.log(obj2.b.c) // 3Copy the code

Deep copy: Method 1: Convert the object to a string using json.stringify, and convert the string to a new object using json.parse

let obj1 = {
    a: 1,
    b: 2,
}
let obj2 = JSON.parse(JSON.stringify(obj1))
Copy the code

Method 2: Copy all hierarchical attributes recursively

Function deepClone (obj) {/ / if the incoming value is not an Object, it does not perform the if (Object. The prototype. ToString. Call (obj)! == '[object object]') return // Let result = obj instanceof Array? [] : {} for (let key in obj) {if (obj. HasOwnProperty (key)) { If the Object is not directly return value result [key] = Object. The prototype. The toString. Call (obj [key]) = = = '[Object Object]'? deepClone(obj[key]) : Console. log(typeof null === 'object') // true console.log(Object.prototype.toString.call(null) === '[object Object]') // falseCopy the code

Method 3: The Lodash library implements deep copy

let obj1 = {
    a: 1,
    b: 2,
}
let obj2 = _.cloneDeep(obj1)
Copy the code

Method 4: Deep copy is implemented by extending method of jQuery

Let array = [1,2,3,4] let newArray = $.extend(true,[],array) // true for deep copy and false for shallow copyCopy the code

Method 5: Make a deep copy of an array using slice

let arr1 = ["1","2","3"]
let arr2 = arr1.slice(0)
arr2[1] = "9"
console.log(arr2) // ['1', '9', '3']
console.log(arr1) // ['1', '2', '3']
Copy the code

Method 6: Use extended operators for deep copy

Let obj2 = {brand: "BMW", price: "380000", length: "5 "} let obj2 = {brand: "BMW", price: "380000", length: "5 "} car, price: "500000" }Copy the code

Js shallow copy and deep copy of the difference and implementation

8. Talk about the js garbage collection mechanism

Js has an automatic garbage collection mechanism. When a value loses its reference in memory, the garbage collection mechanism will find it according to a special algorithm and collect it, freeing the memory.

Tag cleanup (common) (1). Tag phase: The garbage collector iterates from the root object. Each object that can be accessed from the root object is assigned an identity, so that the object is identified as reachable; (2). Clearance stage: Garbage collector will perform linear traversal of heap memory from beginning to end. If an object is not identified as reachable object, the memory occupied by this object will be reclaimed and the original mark marked as reachable object will be cleared for the next garbage collection operation;

Advantages: Simple implementation Disadvantages: May cause a large amount of memory fragmentation

Reference counting method (1). The meaning of reference counting is to track the number of times each value is referenced. When a variable is declared and a reference type is assigned to the variable, the number of references to the value is 1. Conversely, if the variable containing a reference to that value obtains another value, the number of references to that value is reduced by one. (2). When the number of references becomes 0, it means that there is no way to access the value, and the memory space occupied by the value can be reclaimed. In this way, the next time the garbage collector runs, it frees the memory occupied by values that are referenced 0 times.

Advantages: (1). Can immediately recycle garbage

Disadvantages: (1). The increase and decrease of counter value processing is heavy (2). The implementation is complicated (3). Circular references cannot be recycled

9. How do I prevent event bubbling and default events

Standard DOM objects can use the stopPropagation() method of event objects to prevent bubbling, but in IE8 the event objects below prevent bubbling by setting the cancelBubble property of the event object to true

The default event is prevented by the event object preventDefault() method, while IE prevents the default event by setting the event object’s returnValue property to false

10. Function chattering and function throttling

Debounce: The action is not performed after a function has been called for n seconds, and if the function is called again within n seconds the previous action is cancelled and the execution time is recalculated (in the case of frequent triggering, the code is only executed once with sufficient free time)

function debounce(delay, cb) {
    let timer
    return function () {
        if (timer) clearTimeout(timer)
        timer = setTimeout(function () {
            cb()
        }, delay)
    }
}
Copy the code

Underscore for JavaScript topics

Function throttling: The basic idea of function throttling is that the function presets an execution period, executes the action when the action is invoked at a time greater than or equal to the execution period, and then enters the next new period (the JS method only runs once in a certain period of time). For example, a person blinks once in a certain period of time.

function throttle(cb, delay) {
    let startTime = Date.now()
    return function () {
        let currTime = Date.now()
        if (currTime - startTime > delay) {
            cb()
            startTime = currTime
        }
    }
}
Copy the code

JavaScript topics follow the science of underscore

11. Talk about the js event loop mechanism

After the program starts executing, the main program began to perform synchronization task, I met an asynchronous task was put it in the task queue, wait until after completing execution of the synchronization task, js engines will have to view the task queue can perform asynchronous tasks, the asynchronous tasks into synchronization task and begin to execute, after perform the synchronization task to continue to view the task queue. This process is always cyclic, so the process is called event loop, where the task queue is also called event queue. A single threaded JS implements asynchronous task execution through a task queue, giving the impression that it is multithreaded.

12. Differences between arrow functions and ordinary functions

Ordinary functions: (1).this always stands for its direct caller (2). By default, the direct caller is not found and this points to window (3). In strict mode, this is undefined (4) in functions that have no direct callers. Use call, apply, bind bindings, and this refers to the bound object

Arrow functions: (1). When using => to define a function, this refers to the object at which it was defined, not to the object at which it was used. Bind (), call(), and apply() cannot change the reference to (2). It cannot be used as a constructor, that is, the new command cannot be used, otherwise an error (3) will be thrown. You can’t use arguments objects, but you can use… Rest argument (4). Cannot use yield command (5). No stereotype attribute

13. Call (), apply(), bind() differences and implementation

Call (), apply(), and bind() are used to redirect this

Call () : function. call(obj, param1,param2,param3) receives param1,param2, and param3

Apply () : Function. Apply (obj, [param1,param2,param3]) accepts param1,param2,param3

The difference between call and apply is that one parameter does not use [] and the other parameter uses [].

The bind () : Const newFn = funtion. bind(obj, param1,param2) returns a function that requires () to call newFn(param3,param4). Param1,param2, param3, Param4 Four parameters

Call implementation:

Function.prototype.call = function (context, ... args) { var context = context || window; context.fn = this; var result = eval('context.fn(... args)'); delete context.fn return result; }Copy the code

The implementation of Apply:

Function.prototype.apply = function (context, args) { let context = context || window; context.fn = this; let result = eval('context.fn(... args)'); delete context.fn return result; }Copy the code

The implementation of bind:

Function.prototype.bind = function (context, ... args) { if (typeof this ! == "function") { throw new Error("this must be a function"); } var self = this; var fbound = function () { self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments))); } if(this.prototype) { fbound.prototype = Object.create(this.prototype); } return fbound; }Copy the code

Implement a sleep function

Js does not have a sleep() method like Java, but because JS is single-threaded, it can block the main thread with pseudo-dead loops to achieve delayed execution

Function sleep(delay) {let startTime = new Date().getTime(); While (new Date().getTime() -startTime < delay) {continue}}Copy the code

15. The difference between processes and threads

Process: is the smallest unit of CPU resource allocation (it is the smallest unit that can have resources and run independently), is the basic unit of concurrent execution of the program in the process of allocating and managing resources, is a dynamic concept.

Thread: the smallest unit of CPU scheduling (a program running unit based on a process), is a schedulable entity within a process, smaller than the basic unit of independent operation.

A process has one or multiple threads, thread between joint complete process is assigned to the task, for example: if a process is a factory, the factory has its own independent resources between low factory are independent of each other in low thread is a factory worker, multiple workers complete the tasks when one or more workers to work with the factory where workers Shared space

Perfect the concept again: ● Factory resources -> system-allocated memory (a separate block of memory) ● Independent between factories -> independent between processes ● Multiple workers collaborate to complete a task -> multiple threads collaborate to complete a task within a process ● There are one or more workers in a factory -> a process is made up of one or more threads ● Shared space between workers -> The memory space of a program (including code segments, data sets, heaps, etc.) shared between threads of the same process

Discussion on browser multi-process and JS thread

16. New features for ES6, ES7, and ES8

The characteristics of the ES6

Classes are familiar to developers familiar with Java, C, C++ and other languages. ES6 introduces classes, which make OBJECT-ORIENTED programming of JS easier and easier to understand.

ES5 does not support native modularity, and modules are added as an important part of ES6. The functions of the module are mainly composed of export and import. Each module has its own separate scope. The mutual call relationship between modules is to specify the interface exposed by the module through export, and to reference the interface provided by other modules through import. It also creates namespaces for modules to prevent function naming conflicts.

Export ES6 runs in a module that uses export to export multiple variables or functions

// Export let name = 'gg' // export constant export const name = 'gg' // Export multiple variables let a = 2 let b = 4 export {a, Export function myModule(someArg) {return someArg}Copy the code

Once the output of a module is defined, it can be referenced by import in another module.

import {myModule} from 'myModule'
import {a,b} from 'test'
Copy the code

(3) Arrow function This is one of the most exciting features of ES6. => is not just a shorthand for the keyword function, it brings other benefits as well. The arrow function shares the same this with the surrounding code, which is a good solution to the this pointing problem.

(4). Function parameter default Values ES6 supports setting a default value when defining a function. When the function parameter is set to Boolean value false, some problems can be avoided

Function foo(height = 50, color = 'red') {// color) { let height = height || 50 let color = color || 'red' }Copy the code

(5). Template string

// Let name = 'Your name is' + first + '+ last + '.Copy the code

(6). Deconstructing assignment It is convenient to exchange the values of two variables by deconstructing assignment:

let a = 1
let b = 3

[a, b] = [b, a];
console.log(a) // 3
console.log(b) // 1
Copy the code

Get a value from an object:

const student = { name:'Ming', age:'18', city:'Shanghai' } const {name,age,city} = student console.log(name) // "Ming" console.log(age) // "18" console.log(city)  // "Shanghai"Copy the code

(7). Spread operator and rest operator when three points (…) On the right side of the equal sign, or on the argument, is the spread operator

myFunction(... arr) let arr1 = [1, 2, 3, 4] let arr2 = [...arr1, 4, 5, 6] console.log(arr2) // [1, 2, 3, 4, 4, 5, 6]Copy the code

When three points (…) On the left side of the equals sign, or over the parameter, is the REST operator

function myFunction(... arr) { } let [a,...temp]=[1, 2, 4] console.log(a) // 1 console.log(temp) // [2, 4]Copy the code

Object Property shorthand in ES6 allows you to set an object property without specifying the property name

Not using ES6:

const name='Ming',age='18',city='Shanghai';

const student = {
    name:name,
    age:age,
    city:city
};
console.log(student)//{name: "Ming", age: "18", city: "Shanghai"}
Copy the code

Using ES6:

const name='Ming',age='18',city='Shanghai'

const student = {
    name,
    age,
    city
};
console.log(student)//{name: "Ming", age: "18", city: "Shanghai"}
Copy the code

Promise is a solution to asynchronous programming that is more elegant than the traditional solution, callback. It was first proposed and implemented by the community, and ES6 has written it into the language standard, unifying usage, and providing Promise objects natively.

Do not use the ES6

SetTimeout (function() {console.log('Hello') // 1 seconds after output "Hello" setTimeout(function() {console.log('Hi') // 2 seconds after output "Hi"}, 1000)}, 1000)Copy the code

Use the ES6

let waitSecond = new Promise(function(resolve, reject) { setTimeout(resolve, 1000) }); Waitsecond.then (function() {console.log("Hello") // return waitSecond}). Then (function() { Console. log("Hi") // output "Hi" after 2 seconds})Copy the code

Previously JS had no block-level scope. Const and let filled the convenient gap. Const and let were both block-level scopes.

● Let variables cannot be repeatedly declared ● Variables declared by let are only valid in let code blocks

The characteristics of the ES7

(1). Array. Prototype. Includes () includes () function is used to judge whether an Array containing a specified value, if the contains the return true, otherwise returns false

Let arr = ['react', 'Angular ', 'vue'] if (arr.includes('react')) {console.log('react exists ')}Copy the code

The exponent operator ** is introduced in ES7, ** has the same properties as math.pow (..). Equivalent results.

Console. log(math.pow (2, 10)) // outputs 1024 console.log(2**10) // outputs 1024Copy the code

The characteristics of ES8

(1). Async /await support has been added in ES8 for async/await, also known as asynchronous functions, which is a very useful feature. Async /await is a syntactic sugar that solves the problem of callback hell

(2).object.values () Object.values() is a new function similar to Object.keys(), but returns all values of Object attributes, excluding inherited values.

const obj = { a: 1, b: 2, c: Values () const vals = object.keys (obj).map(e => obj[e]) console.log(vals) // [1, 2, 3] // Use Object.values() console.log(Object.values(obj)) // [1, 2, 3]Copy the code

The.object.entries object.entries () function returns an array of key-value pairs for a given Object’s own enumerable properties.

const obj = { a: 1, b: 2, c: 3, ForEach (key=>{console.log('key:'+key+' value:'+obj[key])}) // Do not use object.entries () object.keys (obj) //key:b value:2 //key:c value:3 // Use object.entries () for(let [key,value] of object.entries (obj1)){console.log(' key: ${key} value:${value}`) } //key:a value:1 //key:b value:2 //key:c value:3Copy the code

(4). The String padding in ES8 two instances have been added to the String String. The function prototype. PadStart and String prototype. PadEnd, allows you to an empty String or other String is added to the beginning or end of the original String

String.padStart(targetLength,[padString])
Copy the code

TargetLength: the targetLength to which the current string needs to be filled. If the value is less than the length of the current string, the current string itself is returned. PadString :(optional) padding string. If the string is too long and the length of the filled string exceeds the target length, only the leftmost part is reserved and the rest is truncated. The default value of this parameter is “”.

The console. The log (' 0.0 '. PadStart (4, '10')) / / 10.0 console. The log (' 0.0 '. PadStart (20)) / / 0.00Copy the code
String.padEnd(targetLength,padString])
Copy the code

TargetLength: the targetLength to which the current string needs to be filled. If the value is less than the length of the current string, the current string itself is returned. PadString :(optional) padding string. If the string is too long, the length of the filled string exceeds the target length, only the leftmost part is reserved and the rest parts are truncated. The default value of this parameter is “”.

The console. The log (' 0.0 '. PadEnd (4, '0')) / / 0.00 console. The log (' 0.0 '. PadEnd (10, '0')) / / 0.00000000Copy the code

(5). A comma is allowed at the end of a function argument list

// let f = function(A, b) {... } // let f = function(a, B, c // c // c) {... } // let f = function(a, b, C, d // C) {... } // let f = function(A, b,) {... } // let f = function(a, B, c) {... } / / programmer let C f = function (a, b, C, d, / / change) {... }Copy the code

(6). The Object. GetOwnPropertyDescriptors () Object. GetOwnPropertyDescriptors () function is used to retrieve an Object of all their property descriptors, if you don’t have any own properties, it returns null objects.

const obj2 = {
	name: 'Jine',
	get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
// {
//   age: {
//     configurable: true,
//     enumerable: true,
//     get: function age(){}, //the getter function
//     set: undefined
//   },
//   name: {
//     configurable: true,
//     enumerable: true,
//		value:"Jine",
//		writable:true
//   }
// }
Copy the code

ES6, ES7, ES8 Features stew (ES6, ES7, ES8 Study Guide)

17. How does the performance monitoring platform catch errors

Global capture capture code is written in one place through the global interface, which can be used: (1). The window. The addEventListener (” error “)/window. AddEventListener (” unhandledrejection “) / Document. The addEventListener (‘ click ‘), etc. (2). Framed-level global listening. For example, aiXOS uses interceptor for intercepting. Vue and React have their own error collecting interfaces (3). By wrapping the global function, it can automatically catch exceptions when the function is called (4). Example method rewrite (Patch) to cover the original function, such as console.error rewrite, can also catch exceptions while using the same method

Single point capture a single code block is wrapped in business code, or dotted in the logical flow, to achieve targeted exception capture: (1).try… Throw err (2) in catch. Write a function specifically to collect exception information and call this function (3) when an exception occurs. Write a special function to wrap around other functions, resulting in a new function that behaves exactly like the original function, except that it can catch exceptions when they occur

Research on front-end anomaly monitoring solution

18. Coriolization of functions

In mathematics and computer science, Currization is the technique of converting a function that takes multiple arguments into a series of functions that take one argument

Example:

function add(a, b) { return a + b; // add(1, 2); // add(1, 2); addCurry(1)(2) // 3 addCurry(1)(2) = add(1, 2)Copy the code

Implementation: (1). The simplest way, using the lodash library _. Curry

Function sum(a, b) {return a + b} // Use _. Curry let curriedSum = _. 2) ) // 3 alert( curriedSum(1)(2) ) // 3Copy the code

(2). Custom function implementation

function curry(func) { return function curried(... args) { if (args.length >= func.length) { return func.apply(this, args) } else { return function(... args2) { return curried.apply(this, args.concat(args2)) } } } } let currfn = curry(add) console.log(currfn(1)(3)) // 4Copy the code

Currization of JavaScript topics

19. What does the new keyword do?

Calling the constructor using the new operator actually goes through four steps: (1). Create a new object (2). Assign the constructor’s scope to the new object (so this refers to the new object) (3). Execute the code in the constructor (add attributes, methods for the new object) (4). Return a new object

var obj = {}
obj.__proto__ = Base.prototype
Base.call(obj)
Copy the code

20. What do the following functions output?

What are the output values of.p1. name and p2.name?

var func1 = function(){
    this.name = 'peter'
    return {
        name: 'jack'
    }
}
var p1 = new func1()
-----------------------
var func2 = function(){
    this.name = 'peter'
    return 'jack'
}
var p2 = new func2()

console.log(p1.name) // jack
console.log(p2.name) // peter
Copy the code

If a return statement is used, the value followed by return is returned. If a return statement is not used, undefined is returned by default. In particular, if the function is a constructor, this is returned by default. If the constructor uses a return statement followed by an object, the constructor returns the object; otherwise, this is returned.

Name, b1.info.name, a2.info.name, b2.info.name, b2.info.

var func1 = function(){} func1.prototype = { info : { name : 'peter', age : 25 } } var a1 = new func1() var b1 = new func1() a1.info.name = 'jack' b1.info.name = 'tom' ------------------------ var  fun2 = function(){ this.info = { name : 'peter', age : 25 } } var a2 = new fun2() var b2 = new fun2() a2.info.name = 'jack' b2.info.name = 'tom' console.log(a1.info.name) // tom console.log(b1.info.name) // tom console.log(a2.info.name) // jack console.log(b2.info.name) // tomCopy the code

Name = > < span style = “box-width: 0px; text-align: left;” Name and b2.info.name, a2 and B2 instances have info objects, so the name value of the info object in a2 and B2 instances is changed

(3).a.name and b.name output what?

var func = function(){}
func.prototype = {
    name : 'peter',
    age : 25
}

var a = new func()
var b = new func()

a.name = 'jack'
b.name = 'tom'

console.log(a.name) // jack
console.log(b.name) // tom
Copy the code

The name attribute of the instance object is assigned to jack and name respectively

Function isInstanceOf (child, parent) function isInstanceOf (child, parent)

Instanceof is used to determine whether an instance is of a type, but also to determine whether an instance is of its parent or ancestor type

Implementation:

function isInstanceOf(child, While (true){if(child.__proto__ === parent. Prototype) return true if(child.__proto__ === null) return false child = child.__proto__ } }Copy the code

22. How do I set the expiration time for localStorage

Start by overriding the set method on the prototype so that it can set an expiration time

Storage.prototype.setExpire = (key, value, expire) => {
    let obj = {
        data: value,
        time: Date.now(),
        expire: expire,
    }
    localStorage.setItem(key,JSON.stringify(obj));
}
Copy the code

If the time has expired, remove localStorage and return NULL

Storage.prototype.getExpire= key => { const val = localStorage.getItem('key') if (! val) return val val = json.parse(val) if (Date.now() - val.expire > val.time) { localStorage.removeItem(key) return null  } return val.data }Copy the code

23. How to implement real-time communication between two tabs in browser

Using localStorage, you can realize the communication between multiple tabs in the same browser by listening to storage events. Note: Only multiple tabs of the same browser with the same domain name, same protocol, and same port can communicate. Different browsers do not have this effect.

window.addEventListener("storage",function(event){
            // ....
        },false); 
Copy the code

Event has the following attributes: DomIN: indicates the domain name of the storage space that is changed. Key: the name of the key to be set or deleted. NewValue: If it is a set value, the value is new. Null if the value is deleted; OldValue: the value before the key was changed;

(To be continued, write later)