Front end development interview - Introduction to test questions
JS part
Explain variable promotion
The JavaScript engine obtains all declared variables by parsing the code first, and then runs down line by line. Therefore, a problem is that all statements declared by variables will be promoted to the top of the code, which is called variable promotion
console.log(a) // undefined var a = 1
Promotion execution sequence
The engine splits var a = 1 into var a = undefined and a = 1 and raises var a = undefined to the top
Briefly describe the concept of closure
Closure = sum of functions and accessible variables within functions
-
Characteristics of closure
- Internal functions can always access the parameters and variables declared in the external function in which they are located
- use
3. Disadvantages of closures: closures will lead to excessive memory consumption because variables do not release memory, so the garbage collection mechanism will not destroy the variable
function Person(){ var name = 'wl'; this.getName = function(){ return name; } this.setName = function(value){ name = value; } } const person = new Person() console.log(person.getName()) //wl person.setName('test') console.log(person.getName()) //test console.log(name) // undefined // Solution 2: for (var j = 0; j < op.length; j++) { op[j].onclick = (function(j) { return function() { alert(j); }; })(j); }
### Principle of waste recycling
Garbage collection principles blog
1.js garbage collection mechanism is to prevent memory leakage. The meaning of memory leakage is that when a piece of memory is no longer needed, the fast memory still exists. The garbage collection mechanism is to find unsuitable variables from time to time,
And free the memory they point to.
What are the types of js
1. Basic type(Original type): * String * Number * undefined * null * boolean * symbol(es6) 2. reference type * Object
What is the difference between js reference type and basic type
- Different storage methods
- That is, the basic types do not interfere with each other, and the reference types point to the same memory address
let a = 1 let b b = a b = 2 console.log(a, b) // 1 2 let obj = { name: 'test' } let obj2 = obj1 obj2.name = 'bar' console.log(obj.name) // bar
* Stack memory and heap memory * Stack: store basic types. The stack will automatically allocate memory space and automatically release. Simple data segments occupy a fixed size space * Heap: stores reference types, dynamically allocates memory, and will not be automatically released if the size is variable, * Difference: all variables defined in the method are stored in the stack memory. The memory stack of this method will be destroyed naturally when the method execution ends.
The difference between null and undefined
- Null indicates a null value. Null itself is an object that has a pointer address
- undefined means that does not exist
Why is 0.1 + 0.2 not equal to 0.3
-
Because 0.1 and 0.2 are actually infinite loops after being converted to binary, but the floating-point number clipping scheme adopted by js will lead to precision failure
-
Solution
-
ParseFloat((0.1 + 0.2).toFixed(10))
-
Understanding of prototype chain
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ttrJE6Ki-1625026337021)(./assets/proto.jpg)]
Explain in detail in my blog
1. All reference types can add custom attributes
2. All reference types have their own implicit proto types
3. Each function has its own display prototype
4. All implicit prototypes of reference types point to the display prototype of the corresponding constructor
5. When using a custom attribute of a reference type, if there is no such attribute, it will go to the proto of the reference type (that is, the prototype of the corresponding constructor)
Understanding of this
- In fact, there are only three cases of this
-
- Declared globally pointing to window
-
- this points to who calls a function
-
- For an object from new, this points to the object itself
-
EventLoop
- js gives priority to the execution of synchronization code, which belongs to macro tasks. When js confirms that there are no macro tasks in the call stack, it will scan the micro task queue. If micro tasks are found, all micro tasks in the queue will be executed in batches at one time. Each macro task will be accompanied by a micro task queue
- Macro task:
- script tag
- setTimeout
- setInterval
- I/O
- Micro task
- promise
- mutationObserver
Deep and shallow copy
1.Shallow copy: that is, only the first level attributes are copied, and the copied object is the basic type When copying a basic type, use the equal sign directly. When copying a reference type, use the equal sign for each attribute or value. 2. Deep copy: for the values of all reference types in the attribute, traverse until they are the values of the basic type, and use recursion to realize deep copy ### Recursive method and where commonly used 1.Recursion is the function itself calls itself, or calls itself in the lower level function of its own function. ```js var data = [ { name: "All items", children: [ { name: "Fruits", children: [{name: "Apple", children: [{name: 'green apple'}, {name: 'Red apple'}]}] }, { name: 'staple food', children: [ {name: "rice", children: [{name: 'Northern Rice'}, {name: 'Southern Rice'}]} ] }, { name: 'articles for daily use', children: [ {name: "Computer", children: [{name: 'Lenovo computer'}, {name: 'Apple Computer'}]}, {name: "Tool class", children: [{name: "Hoe"}, {name: "hammer"}]}, {name: "articles for daily use", children: [{name: "shampoo"}, {name: "Shower Gel"}]} ] } ] }] //General traversal implementation var forFunction = function () { var str = "" data.forEach(function(row){ row.children.forEach(function(row){ row.children.forEach(function(row){ row.children.forEach(function(row){ str += (row.name + ";") }) }) }) }) console.log(str) } forFunction() //Recursive traversal implementation var recursiveFunction = function(){ var str = '' const getStr = function(list){ list.forEach(function(row){ if(row.children){ getStr(row.children) }else { str += row.name + ";" } }) } getStr(data) console.log(str) } recursiveFunction() ```
What does the new operator do
1. A new object is created that inherits from the constructor prototype foo.prototype 2. The constructor is executed, passing in parameters, and this this Point to this new instance 3. Judge whether the constructor returns an object. If the returned data structure is an object, it will be replaced new If not, this is the object created in the first step
###Inherit
1. Prototype chain inheritance (take the instance of the parent class as the prototype of the child class)
Features: 1. The inheritable attributes of the instance include: the constructor attribute of the instance, the constructor attribute of the parent class, and the prototype attribute of the parent class. (the new instance will not inherit the properties of the parent instance!)
Disadvantages: 1. The new instance cannot pass parameters to the parent constructor.
2. Single inheritance.
3. All new instances will share the properties of the parent instance. (the properties on the prototype are shared. If one instance modifies the prototype properties, the prototype properties of another instance will also be modified!)
2. Borrowing constructor inheritance
Features: 1. It only inherits the properties of the parent class constructor, but does not inherit the properties of the parent class prototype.
2. Solve the shortcomings of prototype chain inheritance 1, 2 and 3.
3. You can inherit multiple constructor attributes (call multiple).
4. Parameters can be passed to the parent instance in the child instance.
Disadvantages: 1. You can only inherit the properties of the parent constructor.
2. The reuse of constructors cannot be realized. (to be called again every time)
3. Each new instance has a copy of the parent constructor, which is bloated.
3. Combination inheritance
Key point: it combines advantages of the two modes, transmission participation and reuse
Features: 1. It can inherit the attributes on the parent class prototype, pass parameters and reuse.
2. The constructor property introduced by each new instance is private.
Disadvantages: the parent constructor is called twice (consuming memory), and the constructor of the child class will replace the parent constructor on the prototype.
4. Prototype inheritance
Key: wrap an object with a function, and then return the call of the function. The function becomes an instance or object that can add properties at will. object.create() is the principle.
Features: similar to copying an object, wrapped with functions.
Disadvantages: 1. All instances will inherit the properties on the prototype.
2. Reuse cannot be realized. (new instance properties are added later)
5. Parasitic inheritance
Key point: it is to put a shell on the prototype inheritance.
Advantages: no custom type is created, because it only sets a shell to return the object (this), and this function naturally becomes a new object created.
Disadvantages: no prototype is used and cannot be reused.
6. Parasitic combinatorial inheritance
Parasitism: returns an object within a function and calls it.
Combination: 1. The prototype of the function is equal to another instance. 2. Use apply or call to introduce another constructor in the function, which can pass parameters
Key: fixed the problem of composite inheritance
Differences between ES Module and CommonJS Module
- ES Moudule is introduced statically
- Common JS is introduced dynamically
- The former supports tree shaking, while the latter does not
###Promise principle
1.promise is a solution for asynchronous programming. Used to solve the problem of callback hell.
2.promise is a micro task in an event loop. The micro task queue is emptied in each event loop.
3. Once promise is executed, it cannot be cancelled halfway
4.promise errors cannot be captured externally and can only be pre judged internally
5. How to implement in promise is difficult to monitor.
The promise object has three states: pending, completed, and rejected
Restore and reject change the state of promise and take the accepted value as the value of promise
Vue interview questions
The core of Vue
- Data driven view (MVVM) + componentization
Principle of bidirectional binding
Object.definePrototy getter setter Search the Internet casually. There are many getter This method was called setter Is the data updated and return to me configurable:true, //The default is false. Can I delete it
The difference between Vue watch and computed
watch The usage scenario is data When a data in the changes or needs to be executed asynchronously when the data changes watch Normal monitoring and deep monitoring (use) handler of immediate Property can be executed immediately) deep by true You can listen deeply for the value of an object. The same thing: both of them will observe the changes of page data difference: computed Only when the dependent data changes will it be calculated. When the data does not change, it will read the cached data watch You need to execute the function every time, wacth Asynchronous operations are more suitable for data changes. computed principle
Why can't Vue listen to objects and arrays
- Because the reference type is stored in the heap memory, the reference type we usually operate is actually a copy stored in the stack memory, so we can't listen
Why is data a function
- Function scope prevents pollution caused by the same variable of different components
Describe the process of Vue initial update and data update
- Initial update
- Resolve template to render
- Trigger obj getter for defineproprty
- Execute render to generate VNode
- patch(ele, VNode)
- Data update
- Trigger ` ` ` obj setter for defineproptry ` `
- Execute render to generate VNode
- patch(oldVnode, newVnode)
diff algorithm of Vue
- The new and old nodes make diff comparison by comparing the new head, the old tail, the new tail and the old head
- When none of the four methods can match, the key will be used, so the key should be the only value, not index, because the index will change
Compiler procedure for Vue
Complie The main function of is to parse templates and generate rendering templates render,render The main function of is to generate Vnode
- parse - optimize - generate
- parse accepts the original template of the template and generates the corresponding ast according to the nodes and data of the template
- optimize traverses each node of the ast and marks the static node, so that you can know which part will not change. Therefore, when the page needs to be updated, you can reduce the comparison of this part of DOM and improve the performance
- generate generates a perfect ast from the first two steps to form a render string, and then converts the render string into a rendering function through a new Function
Describe Vuex
- First of all, vuex is applicable to the transfer of values between some components at the same level or components that are completely unrelated
- State: values that need to be shared between components can be stored in state
- Actions: it stores asynchronous operations or batch synchronous operations. The components call actions through dispatch
- Changes: it stores the state modification actions of some synchronization methods, which are called through commit
- The biggest difference between actions and changes is that the former is asynchronous and the latter is synchronous
Try to simulate vnode with js
// html code < div class = "div container" id = "div" > < p > vnode < / P > < div > < P style = "font size: 12px" > try to describe v-node by using JS < / P > < / div > < / div >
// vnode simulated with js object { tag: 'div', props: { className: 'div-container', id: 'div' }, children: [ { tag: 'p', children: 'vnode' }, { tag: 'div', children: [ tag: 'p', props: { style: 'font-size: 20px' }, children: 'try to describe V-node by using js' ] } ] }
Implementation principle of Vue router
- First, there are two modes: hash and history
- Implementation principle of hash: monitor window Hashonchange event hash mode routing with # number
- history takes advantage of the new APIs pushstate and popState in html5
Parent child component lifecycle
- Parent beforecreated - > parent created - > parent beforemounted - > child beforecreated - > child created - > child beforemounted - > child mounted - > parent mounted
Webpack interview questions
devser ##performance optimization 1. css compress css optimize-css-assetsWebpackPlugin mini-css-extrect-plugin 2. js Compress the production environment automatically mode:'production' html Compression re htmlPlugin minfigy Two properties of js Sequential loading usage 3. The optimized configuration is divided into two types: development environment and production environment, ##The development environment optimizes the speed of packaging and construction. Optimize code debugging. *HMR Module hot swap builds faster *source-map If the post build code makes an error, an error message will be prompted after the build ##The production environment optimizes the speed of packaging construction. Optimize code performance *Packing speed oneOf -- babel cache _dll Repackage third-party libraries DllLinkPlugin adopt cnd Link reference externals *Cache( hash-chunkhash-contenthash) *Optimized performance tree shaking //Must es6, sideEffect of useless code will be automatically cleared: [comment] 4. code spliting Code split single entry-Just one bundle Configuration to multiple (via import Introduced js Code will be split) commonsChunkPlugin 5.Lazy loading 6.pwa It is an offline packaging technology and can be accessed offline workboxwebpackPlugin.get 7.Multi process packaging, you can prompt the packaging speed ### Which plug-ins are useful in webpack 1.optimize-css-assetsWebpackPlugin css compress 2. speed-measure-webpack-plugin Packaging speed analysis is not in plugin Introduced in. Instead, instantiate it first, smp.wrap()Method package 3. webpack-bundle-analyzer Volume analysis 4. terser-webpack-plugin Multi process, multi instance and code compression optimization Compression in 5. CommonsChunkPlugin DLLPlugin That is to separate the third-party library from our own code and package only the project's own code each time
Differences between module bundle chunk s
- Module - source code file (module)
- chunk - code composed of multiple modules
- bundle - output file
Difference between Loader and Plugin
- Loader is a translator that helps webpack identify how to package files of the corresponding type
- Plugin will automatically help us do something in the corresponding life cycle of webpack
Webpack build process
- Initialization parameters: through shell command and config JS merge parameters
- Start compilation: initialize the Compiler object through parameters and execute the run method
- Determine entry: determine the entry according to the entry
- Compilation module: start from the entry file, use the loader to start translation, and confirm that all dependent files have established mutual dependencies through recursion
- Output resources
- Write memory
Optimize performance with webpack
1. optimization```sourcemap``` 2. utilize CDN accelerate => The static resource path is modified to cdn route 3. utilize```Tree shaking```Only supported by default es6 Moudle 4. code spliting(Code segmentation you can search casually. Many of them are actually configuration items)
Improve the efficiency of Web pack packaging
-
happyPack
-
dll packaging
-
Reduce the search scope of the loader. The loader can configure exclude because of node_modules are actually packaged, so third-party files do not need to be packaged again
###How to solve cross domain problems
- For jsop and jsonp, the request must be supported by the other server. The advantages are simple, good compatibility, and the disadvantages are 🈲 It supports get method, which has limitations and is not safe
- cors CORS needs
What happens when you enter URLs
1.Domain name resolution, the browser will url Resolve the of the corresponding server IP address 2. The browser establishes a connection with the target server Tcp Link (three handshakes) 3. The browser sends a message to the server once Http Request message 4. The server returns a message to the browser HTTP response message 5. Render with browser 6. close TCP Link, wave four times*Step 1 of browser rendering.html Parse out Dom2.css Parse out style Rules3.The two are generated by association render4.layout Layout basis render Calculate the information of each node 5.painting Render the page according to the calculated information
Force cache and negotiation cache
Forced caching is when we first request resources http Set an expiration time for the response header. Within the effective time, it will be obtained directly from the browser. Common http Response header fields, such as cache-Control and Expires Negotiation cache is through http Response header field etag perhaps last-Modified Determine whether the resources on the server are modified, if so, retrieve them from the server, if not, 304 point to the browser cache
###http1.0/1.1/2.0
1.HTTP1.0 defines three request methods: get post head. 1.1 six request methods are added: options put patch delete trace connect
2. Cache processing: in http1 In 0, if modified since and expires in the header are mainly used as the criteria for cache judgment,
HTTP1.1 introduces more cache control strategies, such as Entity tag, if unmodified since, if match, if none match and other optional cache headers to control cache strategies.
3.host header processing:
4. Long link
##2.0 vs. 1.1 New binary format( Binary Format): HTTP1.x The parsing of is text-based. There are natural defects in format parsing based on text protocol, and the expression forms of text are diverse, There must be many scenarios to consider for robustness, but binary is different. Only the combination of 0 and 1 is recognized. Based on this consideration HTTP2.0 The binary format is adopted for protocol analysis, which is convenient and robust. Multiplexing( MultiPlexing): That is, connection sharing, that is, each request Are used as connection sharing mechanisms. One request Corresponding to one id,There can be more than one on such a connection request,Of each connection request Can be randomly mixed together, The receiving party may request of id take request Then belong to different server requests. header Compression: as mentioned above, yes, as mentioned earlier HTTP1.x of header With a lot of information, and it has to be sent repeatedly every time, HTTP2.0 Designed specifically for header compression HPACK Algorithms, using encoder To reduce the need for transmission header size, Each communication party cache A copy header fields Table, which avoids duplication header The size of transmission is reduced. Server push( server push): The server push can accompany the resources required by the client index.html It is sent to the client together, which saves the client from repeating the request. Because there are no requests, connections and other operations, static resources can be pushed by the server to greatly improve the speed. For example, my web page has a sytle.css Request received at the client sytle.css Data at the same time, The server will sytle.js The file is pushed to the client when the client tries to get it again sytle.js You can get it directly from the cache without sending any more requests. ###http status code 1xxx A temporary response is a status code that indicates a temporary response and requires the requester to continue the operation 2xx(Success) status code indicating that the request was processed successfully 3xx(Redirection) indicates that further operations are required to complete the request; Typically, these status codes are used for redirection 4xx(Request error) these status codes indicate that the request may be in error and hinder the processing of the server 5xx(Server error) these status codes indicate that the server encountered an internal error while trying to process the request. These errors may be the server itself, not the request
/1.Structure of array // const ARRAY = ['Xiaoshi', 'Xiaowang'] // let [ xs, xw ] = ARRAY // console.log(xs) //Template string for es6 //Line breaks can appear directly in the content // 2. Splicing of variables // let a = 'small stone' // let b = `${a} is the fairy '; // console.log(b) //Simplified writing of es6 objects // let name ='1'; // const obj ={ // name // } //Arrow function // 1. Characteristics of arrow function // This is static. This always points to the value of this under the function declaration //Call method call // 2. Cannot be instantiated as a construction object // The arrow function has no rutuen // let arr =[ // { // id:'1', // c:[ // { // id:2, // }, // { // id:3, // } // ] // } // ]; // let c; // let res = arr.filter(item =>{ // c = item.c.filter(child => child.id==2) // }) // console.log(c)
//rest parameter // args parameter must be placed last // function date(...args) { // console.log(args) // } // date({id:'1',name:'wl'}) //Extended operation // let arr =['wk','li1'] // function box() { // console.log(arguments) // } // box(...arr) //The symbol data type is similar to a string //Object loop // let user = {name:1,id:'2'} // for(let [key, vlaue] of Object.entries(user)) { // console.log(`${key}`) // } // let user = new Map() // user.set('name', 'John') // user.set('age', '30') // for (let [key, value] of user.entries()) { // console.log(`${key}:${value}`) // name:John, then age:30 // } //Array loop array let arr = [1,2,4,5,7] // arr.forEach(function(elem, index, array) { // if (arr[i] == 2) { // continue // } // console.log(elem, index) // }) //forEach does not support continue and break //map returns a new array. Each element is the result of calling func // let result = arr.map(function(value) { // value += 1 // console.log(value) // return value // }) // console.log(arr, result) //filter() returns an array of qualified elements // let result = arr.filter(value => value==2) // console.log(arr, result) // boolean returned by some() to judge whether any element meets the func condition // let ret = arr.some(item => item==8) // console.log(arr, ret) //every() returns boolean and judges that each element meets the func condition // let ret = arr.every(item =>{ // console.log(item) // item ==7 // }) // console.log(arr, ret) //reduce() accepts a function as an accumulator // let sum = arr.reduce(function(prev, cur, index, array) { // return prev + cur // }, 0) // console.log(sum) // let max = arr.reduce(function(prev, cur) { // return Math.max(prev, cur) // }) // console.log(max) // let res = arr.reduce(function(prev, cur) { // prev.indexOf(cur) == -1 && prev.push(cur) // return prev // }, []) // console.log(res)
//Array traversal in es6 // for (let item of arr) { // console.log(item) // // if(item ==4) { // // break // // } // } // for (let item of arr.values()) { // console.log(item) // } // for (let item of arr.keys()) { // console.log(item) // } // for (let [index, item] of arr.entries()) { // console.log(index, item) // } //Array.from() // let arrLike = { // 0: 'a', // 1: 'b', // 2: 'c', // length: 3 // } // let ret = Array.from({ // length: 3 // }, function() { // return arrLike // }) // console.log(ret) //Array.fill() // The fill() method fills all elements in an array from the start index with a fixed value, excluding the end index // arr.fill(9,3,4) / / the first element is the replacement value. / / the second is the start value and the third is the end value // console.log(arr) //Array.find() / / returns the value of the first element in the array // let ret = arr.find(item => item<5) // console.log(ret) // let ret = arr.findIndex(item => item==5) // console.log(ret) //Array.copyWithin() / / within the current array, copy the members at the specified location to other locations, and then return the current array // console.log(arr.copyWithin(1,3)) //Function arrow function // let pow = x => x * x // console.log(pow(2))
//Object copies the object and replaces it with the same one // const obj={ // id:1, // name: 'w' // } // const obj2 ={ // name: 'wl' // } // const obj3 = Object.assign(obj,obj2) // console.log(obj3) //Class declaration class // class Animal { // constructor(type) { // this.type = type // } // walk() { // console.log( `I am walking` ) // } // } // let dog = new Animal('dog') // let monkey = new Animal('monkey') // console.log(dog,monkey) // class Animal { // constructor(type) { // this.type = type // } // walk() { // console.log( `I am walking` ) // } // static eat() { // console.log( `I am eating` ) // } // } // let dog = new Animal() // console.log(dog.eat())
// Symbol // const grade = { // Zhang San:{ // address: 'xxx', // tel: '111' // }, // Li Si:{ // address: 'yyy', // tel: '222' // }, // Li Si:{ // address: 'zzz', // tel: '333' // }, // } // console.log(grade) // const stu1 = Symbol('li Si ') // const stu2 = Symbol('li Si ') // const grade = { // [stu1]: { // address: 'yyy', // tel: '222' // }, // [stu2]: { // address: 'zzz', // tel: '333' // }, // } // console.log(grade) // console.log(grade[stu1]) // console.log(grade[stu2]) // const sym = Symbol('imooc') // class User { // constructor(name) { // this.name = name // this[sym] = 'imooc.com' // } // getName() { // return this.name + this[sym] // } // } // const user = new User('xiecheng') // console.log(user.getName()) // for (let key in user) { // console.log(key) // } // for (let key of Object.keys(user)) { // console.log(key) // } // for (let key of Object.getOwnPropertySymbols(user)) { // console.log(key) // } // for (let key of Reflect.ownKeys(user)) { // console.log(key) // }
//Eliminate magic string // const shapeType = { // triangle: Symbol(), // circle: Symbol() // } // function getArea(shape) { // let area = 0 // switch (shape) { // case shapeType.triangle: // area = 1 // break // case shapeType.circle: // area = 2 // break // } // return area // } // console.log(getArea(shapeType.triangle)) //set // let arr1 = [1, 2, 3, 4] // let arr2 = [2, 3, 4, 5, 6] // //Intersection // let s1 = new Set(arr1) // let s2 = new Set(arr2) // let result = new Set(arr1.filter(item => s2.has(item))) // console.log(Array.from(result)) // //Difference set // let arr3 = new Set(arr1.filter(item => !s2.has(item))) // let arr4 = new Set(arr2.filter(item => !s1.has(item))) // console.log(arr3) // console.log(arr4) // console.log([...arr3, ...arr4]) // const str = 'imooc' // console.log(str.includes('mo')) // console.log(str.startsWith('im')) // console.log(str.endsWith('mooc')) // const newStr = str.repeat(10) // console.log(newStr)
// Number binary // Number.isFinite() // Used to check whether a value is finite, that is, it is not infinite. // Number.isFinite(15) // true // Number.isFinite(0.8) // true // Number.isFinite(NaN) // false // Number.isFinite(Infinity) // false // Number.isFinite(-Infinity) // false // Number.isFinite('foo') // false // Number.isFinite('15') // false // Number.isFinite(true) // false // const a = 0B0101 // console.log(a) // const b = 0O777 // console.log(b) // Number.isInteger() / / used to judge whether a value is an integer // Math. The TRUNC () method is used to remove the decimal part of a number and return the integer part. // console.log(Math.trunc(5.5)) // console.log(Math.trunc(-5.5)) //Proxy // let o = { // name: 'xiaoming', // age: 20 // } // let handler = { // get(obj, key) { // return Reflect.has(obj, key) ? obj[key] : '' // } // } // let p = new Proxy(o, handler) // console.log(p.name) // Promise .reject() // new Promise(function(resolve) { // resolve(42) // }) // Promise.resolve(42).then(function(value) { // console.log(value) // }) // var p1 = Promise.resolve(1) // var p2 = Promise.resolve(2) // var p3 = Promise.resolve(3) // Promise.all([p1, p2, p3]).then(function(results) { // console.log(results) // [1, 2, 3] // }) // function getPromise(url) { // return new Promise((resolve, reject) => { // ajax(url, res => { // resolve(res) // }, err => { // reject(err) // }) // }) // } // getPromise('static/a.json') // .then(res => { // console.log(res) // return getPromise('static/b.json') // }).then(res => { // console.log(res) // return getPromise('static/c.json') // }).then(res => { // console.log(res) // }).catch(err => { // console.log(err) // })
//git undo last commit // git reset HEAD^ //git push -f Force push //git brabch -a view and clean up remote branches // git push origin --delete dev // git remote show origin / / view the remote warehouse information //git branch -d clear local branch // git remote -v view the current warehouse address // git remote add add add warehouse address set yes delete // Pull the remote warehouse information using git fetch (it will not be merged automatically); // Use git reset --hard origin / branch name command to completely overwrite the remote warehouse with the local warehouse. //git revert // The git reset command will change the previous version record, which may result in failure to submit to the remote warehouse; // The git revert command will only revoke the code of a certain version, and then add a new version record in the current branch; // git revert will only undo the code of the specified version, not all versions after the specified version. //git reflog recovery //git rebase is similar to git merge in function. It can record version changes and can be easily modified or revoked // After the git merge command is merged, the version records will be in chronological order, and a merge branch version will be generated automatically //Git cherry pick merges another branch