May interview summary of the front end questions, individual topics with personal understanding, do not guarantee accuracy, welcome to exchange corrections ~😀
What is a prototype?
- There are two types of prototypes: constructor prototypes, called prototypes; Instance (object) prototypes are called __proto__
Relationships between archetypes?
- On instance objects created by the constructor, the __proto__ attribute points to the constructor’s Prototype attribute
What are constructors and constructors?
- By default, every function in js is a constructor, also known as a class, so the prototype chain on the constructor has
ƒ Function() {[native code]}
The constructor prototype has a constructor property on it that points to the constructor itself - The key to being a constructor is having the –>prototype attribute (instance doesn’t have one)
function Fa() {} Fa. Constructor ƒFunction() { [native code] }
Copy the code
- A new instance cannot be created from new because it is not a constructor –> has no prototype property
const son = new Fa()
son.constructor
/ / ƒ Fa () {}
const subSon = new son()
// VM5278:1 Uncaught TypeError: son is not a constructor
at <anonymous>:1:16
Copy the code
- A diagram shows what the constructor wants to do
- Some people might put it
__proto__
和prototype
The confusion. In translation terms, they can both be called prototypes, but they are two very different things.
Function prototype is the __proto__ of all instances constructed using the new function. Functions are also objects, so functions have both __proto__ and prototype.
Author: Yu Tengjing Link: juejin.cn/post/684490… The copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.
What is the prototype chain?
- The __proto__ property of the instance prototype object owned by the instance refers to the prototype property of the constructor prototype object, and the __proto__ property on the prototype object of the constructor refers to the prototype of the parent constructor, and so on, The pointing relationship established by __proto__ is called a prototype chain
What does the prototype chain do?
- When an instance accesses an attribute, it looks for its own traversable attribute, then up the prototype chain, and returns undefined if it can’t find it
- Stu.proto.proto. proto, until null is encountered, undefined is returned
- Function: Define the class method on the prototype, this way, all instances can access the method, and this method only takes up a memory, save memory, this reference can correctly refer to the class instance.
- Note: Properties defined by this method cannot pass because they are not their own properties
Object.keys()
The enumeration
function Engineer(workingYears) {
this.workingYears = workingYears;
}
// Arrow functions cannot be used. The arrow function's this is declared in context
Engineer.prototype.built = function() {
// this is the function caller
console.log('I've been workingThe ${this.workingYears}For years, my job is to turn the screws... `);
};
const engineer = new Engineer(5);
// This points correctly to the instance, so this.workingYears is 5
engineer.built(); // => I have been working for 5 years, my job is to turn screws...
console.log(Object.keys(engineer)); // => [ 'workingYears' ]
Copy the code
- Advantages: This method can be accessed by all instances, and it takes up only one memory, saving memory, and pointing to this correctly points to instances of the class.
- Non-enumerable examples:
function Engineer(workingYears) {
this.workingYears = workingYears;
}
// Arrow functions cannot be used. The arrow function's this is declared in context
Engineer.prototype.built = function() {
// this is the function caller
console.log('I've been workingThe ${this.workingYears}For years, my job is to turn the screws... `);
};
const engineer = new Engineer(5);
// This points correctly to the instance, so this.workingYears is 5
engineer.built(); // => I have been working for 5 years, my job is to turn screws...
console.log(Object.keys(engineer)); // => [ 'workingYears' ]
Copy the code
- Examples of enumerable methods:
function Engineer(workingYears) {
this.workingYears = workingYears;
this.built = function() {
console.log('I've been workingThe ${this.workingYears}For years, my job is to turn the screws... `);
};
}
const engineer = new Engineer(5);
console.log(Object.keys(engineer)); // => [ 'workingYears', 'built' ]
Copy the code
- Common: Array. Prototype. Slice, Object. The prototype. The toString is defined in the function prototype.
- In essence, ES6 class is the syntactic sugar of the constructor.
- ES6 classes are constructors, and the class methods are defined in the constructor’s Prototype, so you can understand why class methods are not enumerable.
- Archetypal inheritance + composite inheritance
// Prototype inheritance
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
// Give subclasses access to static properties on the parent class, which are defined on the constructor itself
// For example, if the parent class has the person. say attribute, the child class Student can be accessed through Student
subClass.__proto__ = superClass;
}
var Shape = function Shape(x, y) {
this.x = x;
this.y = y;
};
var Circle = (function(_Shape) {
_inheritsLoose(Circle, _Shape);
function Circle(x, y, r) {
var _this;
// Combinatorial inheritance
_this = _Shape.call(this, x, y) || this;
_this.r = r;
return _this;
}
var _proto = Circle.prototype;
_proto.draw = function draw() {
console.log(
'\u753B\u4E2A\u5750\u6807\u4E3A (' +
this.x +
', ' +
this.y +
')\uFF0C\u534A\u5F84\u4E3A ' +
this.r +
' \u7684\u5706'
);
};
return Circle;
})(Shape);
Copy the code
What are the ways of inheritance?
(1) use constructor +call/apply to implement inheritance
Function Parent(argument) {this.name=' Parent '; } Parent.prototype.say=function(){} function Child(argument) { Parent.call(this); This. Age =11; this. Age =11; this.age=11; } var child = new Child(); console.log(child); // Child {name: "parent", age: 11}Copy the code
The disadvantage is that you can only inherit properties from the parent instance, not from the prototype chain. (2) Inheritance with the help of prototype chain
Function Parent1(argument) {this.name='parent'; Enclosing the age = [1, 2, 3]; } function Child1(argument) { this.name='child'; } Child1.prototype=new Parent1(); Var child11 = new Child1(); var child11 = new Child1(); console.log(child11) // Child1 {age: 11 , __proto__: Parent1} / * * * * * * * * * * * * * * * * * * * prototype chain inherited weakness * * * * * * * * * * * * * * * * * * * * / var child12 = new Child1 (); child11.age.push(4); // Add an element console.log(child11.age,child12.age) to the reference property of one of the instances // Find that both prints [1, 2, 3, 4]Copy the code
Disadvantages: When a parent class has a reference attribute, due to the nature of the prototype object, the __proto__ of multiple instances is the same, and the reference attribute does not open a new address when new, so when one instance object changes the value of the reference attribute, the other object will also change. (3) the way constructors and prototype chains are combined
Function Parent3(argument) {this.name='parent'; Function (){} function Child3(argument) {parent3.call (this); // combine constructor this.type='test'; } Child3.prototype=new Parent3(); Var child31 = new Child3(); var child32 = new Child3(); console.log(child31,child32); child31.age.push(4); console.log(child31.age,child32.age); .// [1, 2, 3, 4] [1, 2, 3]Copy the code
This approach solves the problem of the first two approaches. Disadvantages: The constructor of the parent class is executed twice. Optimize: put the top
Child3.prototype=new Parent3();
Copy the code
Switch to
Child3.prototype=Parent3.prototype;
Copy the code
The above method is still inadequate, because whenever an object is inherited from the prototype chain, its constructor prints Parent3, i.e. there is no way to confirm whether child31 instance was created by its parent or child class. Reason: Child3 shares a prototype with its parent Parent3. The Child itself has no constructor and, since it inherits its parent class, treats its parent class’s constructor as its own. Solution: Put the top
Child3.prototype=Parent3.prototype;
Copy the code
Switch to
Child3.prototype=Object.create(Parent3.prototype); Create will return a new Object that inherits from Parent3, and then let Child3 inherit from Parent3. Child3.prototype.constructor=Child3; // Modify Child3's constructorCopy the code
So that’s the perfect way to write combinatorial inheritance plus archetypal inheritance.
// The combination of the two
function Parent3(argument) {
this.name='parent';
this.age=[1.2.3];
}
Parent3.prototype.say=function(){}
function Child3(argument) {
Parent3.call(this); // Combine the constructor
this.type='test';
}
Child3.prototype=Object.create(Parent3.prototype);
Child3.prototype.constructor=Child3; // Combine the prototype chain
var child31 = new Child3();
var child32 = new Child3();
console.log(child31,child32);
child31.age.push(4);
console.log(child31.age,child32.age); .// [1, 2, 3, 4]
Copy the code
What does object.create do?
- The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object
const person = {
isHuman: false.printIntroduction: function () {
console.log(`My name is The ${this.name}. Am I human? The ${this.isHuman}`); }};const me = Object.create(person);
me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten
me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"
me.__proto__===person; // true
Copy the code
An interview question related to the prototype encountered in a recent college recruitment interview
I was recently interviewed by a large company.
function Page() { return this.hosts; } Page.hosts = ['h1']; Page.prototype.hosts = ['h2']; const p1 = new Page(); const p2 = Page(); console.log(p1.hosts); console.log(p2.hosts); Copy the codeCopy the code
TypeError: Cannot read property ‘hosts’ of undefined is displayed. If you return the object with new, the object is directly used as the result of new, so P1 should be the result of this.hosts. In new Page(), this is a page.prototype target object, so this.hosts can access page.prototype. hosts ([‘h2’]). So p1 is equal to [‘h2’], [‘h2’] has no hosts property so return undefined. Console. log(p2.hosts) returns an error. P2 is the result of a call to the Page constructor directly. This refers to the global object, which has no hosts property. Accessing hosts from undefined is an error. Author: Yu Tengjing Link: juejin.cn/post/684490… The copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.
Proxy implements the observer pattern
const observerQueue = new Set(a)const observe = (fn) = > observerQueue.add(fn)
const observable = (obj) = >
new Proxy(obj, {
set(tgt, key, val, receiver) {
const result = Reflect.set(tgt, key, val, receiver)
observerQueue.forEach((v) = > v())
return result
},
})
const person = observable({ age: 25.name: "Mike" })
const print = () = > console.log(`${person.name} is ${person.age} years old`)
observe(print)
person.name = "LiHua"
// Lihua is 25 years old
person.age = 45
// Lihua is 45 years old
Copy the code
Common.js compared to ES6’s Module
- ES6 static analysis, dynamic reference, output is the reference of the value, the value of the original module changes, the reference also changes, that is, the value of the loaded value.
- The CommonJS module is run time loaded, and the ES6 module is compile time output interface.
- CommonJS loads the whole module, that is, all the interfaces in it. ES6 can load one of the interfaces (methods) separately.
- CommonJS this points to the current module, ES6 this points to undefined
- The CommonJS module prints a copy of the value, the ES6 module prints a reference to the value.
———————————————— Copyright notice: This article is originally published BY CSDN blogger “Snow is Melting”. It is subject to CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement. The original link: blog.csdn.net/lhjuejiang/…
What is the difference between yield and no value?
- Yield passes the value each time next is called, which will be returned after the last yield statement
- If no value is passed, the value is undefined
/ / value
function *foo(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return (x + y + z)
}
let it = foo(5)
console.log(it.next()) // => {value: 6, done: false}
console.log(it.next(12)) // => {value: 8, done: false}
console.log(it.next(13)) // => {value: 42, done: true}
/ / no value
function *foo(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return (x + y + z)
}
let it = foo(5)
console.log(it.next()) // => {value: 6, done: false}
console.log(it.next()) // => {value: 8, done: false}
console.log(it.next()) // => {value: 42, done: true}
VM5628:7 {value: 6.done: false}
VM5628:8 {value: NaN.done: false}
VM5628:9 {value: NaN.done: true}
Copy the code
Yield common use
function *fetch() {
yield ajax(url, () = > {})
yield ajax(url1, () = > {})
yield ajax(url2, () = >{})}let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()
Copy the code
The execution order of async functions
- Statements decorated with await in async are executed synchronously
- Async returns a promise that the function will be executed as a callback when the external stack ends
let c = 0
let d = async () => {
c = c + await 10
console.log('Inside the function 1')
await console.log('Inside of function 2', c)
console.log('Inside the function 3'.)}undefined
d()
c++
console.log(Outside of the function)
VM2692:3Function outsideVM2618:4Function of the internal1
VM2618:5Function of the internal2 10
VM2618:6Function of the internal3
Copy the code
Both Promise. Race and Promise. All
const p1 = new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('P1 ready for execution')
resolve(P1 executed.)},1000)})const p2 = new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve('P2 executed')},2000)})const p3 = new Promise((resolve, reject) = > {
setTimeout(() = > {
reject('p3 execution failed ')},3000)})Promise.race([p1, p2, p3]).then(res= > console.log(res), err= > consoleLog (err) p1 Ready to execute P1 is executedPromise.all([p1, p2, p3]).then(res= > console.log(res), err= > consoleLog (err)) P1 prepares to execute P3Copy the code
Handwritten, simplified versions of promises
- Reference address: Promise/A+ specification
- Simplified version implementation link
/ / <! -- Simple promise -->
const PENDING = "pending"
const RESOLVE = "resolve"
const REJECT = "reject"
function MyPromise(fn) {
const that = this
that.status = PENDING // MyPromise internal state
that.value = null // Pass the values of resolve and reject
that.resolveCallbacks = [] // Save the resolve callback in then
that.rejectCallbacks = [] // Save the reject callback in then
New MyPromise((resolve,reject)=>{resolve(1)})
function resolve(val) {
if (that.status === PENDING) {
that.status = RESOLVE
that.value = val
that.resolveCallbacks.forEach(cb= > cb(that.value))
}
}
New MyPromise((resolve,reject)=>{reject(1)})
function reject(val) {
if (that.status === PENDING) {
that.status = REJECT
that.value = val
that.rejectCallbacks.forEach(cb= > cb(that.value))
}
}
New MyPromise((resolve,reject)=>{}) fn=(resolve,reject)=>{}
try {
fn(resolve, reject)
} catch (error) {
reject(error)
}
}
// Add the then method to the prototype
MyPromise.prototype.then = function (onFulfilled, onRejected) {
const that = this
// Check whether the passed is a function
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
onRejected = typeof onRejected === 'function' ? onRejected : r= > {
throw r
}
// If there is asynchronous code inside the Promise, then the Promise is still PENDING.Add the then functions to the callback array, and when the asynchronous processing is complete, call resolve or Reject inside MyPromiseif (that.status === PENDING) {
that.resolveCallbacks.push(onFulfilled)
that.rejectCallbacks.push(onRejected)
}
// When the state inside a Promise is already resolve, the function inside then is called and passed the value
if (that.status === RESOLVE) {
onFulfilled(that.value)
}
When a Promise is reject internally, the callback function in then is called and passed
if (that.status === REJECT) {
onRejected(that.value)
}
}
// Self-fulfilling Promise
new MyPromise((resolve, reject) = > {
setTimeout(() = > {
resolve(1)
reject(2)},0)
}).then(res= > {
console.log(res)
}, err= > {
console.log(err)
})
// mypromise.resolve (4).then().then(res => console.log(4)
Copy the code
Considerations for async and await to meet EventsLoop
- What is “await”?
In general, we can takeasync function f() {
await p
console.log('ok'}}function f() {
return RESOLVE(p).then(() = > {
console.log('ok'RESOLVE(p) = RESOLVE(p)Promise.resolve(p) ", but with a subtle but important distinction: p is alreadyPromiseInstance,Promise.resolve returns p directly rather than making a new promise. Personally speakingPromiseResolve's "optimize" behavior probably does more harm than good, but since it's already written into the standard, it's unlikely to change. 】 The problem with older versions of V8 was that similar radical optimizations were performed when P was an already-settled promise, resulting in different execution timings than non-Settled promises. For example, add one to your async2awaitStatement, the old version behaves the same as the new version.Copy the code
Examples:
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')}async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')},0)
new Promise(resolve= > {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')})console.log('script end')
// script start => async2 end => Promise => script end => promise1 => promise2 => async1 end => setTimeout
Copy the code
Resolution:
whenawaitAnd then there's aasyncAfter the function is executed, that is:async function async1() {
await async2()
console.log('async1 end')}async function async2() {
console.log('async2 end'} since async2 returns a promise after execution, it is equivalent toasync function async1() {
return new Promise((res, rej) = > {
console.log('async2 end')
}).then(() = > {
console.log('async1 end')})} same resultCopy the code
What’s the difference between null and undefined
-
Null: Number(null) === 1 false
-
Undefined means no value, undefined, Number(undefined) === NaN false
-
ParseInt (null) returns NaN, and Number(null) returns 0
-
ParseInt (undefined) returns NaN, and Number(undefined) returns NaN
How to correctly determine the value of undefined in the business
- Note: Avoid using == because
null= =undefined
true
0= =undefined
false
' '= =undefined
false
Copy the code
- Correct judgment method
1Or use = = = =if(backgroundAudioManger === undefined)...2, the use oftypeof
if(typeof backgroundAdudioManager == 'undefined')
Copy the code
Handwritten implementation of call,apply,bind
- call
Function.prototype.myCall = function(context) {
if ( typeof this! = ='function' ) throw new TypeError('Error')
// If the context is passed as a base type, you can't bind the fn function, so
if (typeof context === 'object') {
context = context || window;
} else {
context = Object.create(null)
}
context = context || window
// If the context has fn, it will be overwritten and cleared
// newContext.fn = this
// Use the Symbol () unique data type to avoid FN collisions
let fn = Symbol('fn')
context[fn] = this
let args
let result
if ([...arguments][1]) {
args = [...arguments].slice(1)
result = newContext.fn(args)
} else {
result = newContext.fn()
}
delete context[fn]
return result
}
function fn () {
console.log(this.a, this)}const obj = {
a: 21
}
fn.myCall(obj)
Copy the code
- apply
Function.prototype.myApply = function(context) {
if (typeof this! = ='function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
// There is a difference between processing parameters and call
if (arguments[1]) { result = context.fn(... arguments[1])}else {
result = context.fn()
}
delete context.fn
return result
}
Copy the code
- bind
Function.prototype.myBind = function (context) {
if (typeof this! = ='function') {
throw new TypeError('Error')}const _this = this
const args = [...arguments].slice(1)
// Return a function
return function F() {
// Since we return a function, we can new F(), so we need to determine
if (this instanceof F) {
return new_this(... args, ... arguments) }return_this.apply(context, args.concat(... arguments)) } }Copy the code
Implement a new method by hand
- In the new principle section, link to the prototype, obj = object.create (con.prototype)
function _new(. arg){
let obj = {}
let con = [].shift.call(arguments)
obj.__proto__ = Object.create(con.prototype) // Link prototypes
constret = con.call(obj, ... arg);// Change the direction of this
return ret instanceof Object ? ret : obj;
}
Copy the code
- Reference address: Link
function objectFactory (FromFn, ... args) {
// Bind the prototype
var obj = Object.create(FromFn.prototype)
// Bind the parameters passed to the object
var result = FromFn.apply(obj, args)
// If null is returned, the original object is returned
return typeof result === 'object' ? result || obj : obj
}
Copy the code
Symbol() is different from symbol.for () and symbol.keyfor ()
- Reference links: links
- Symbol() returns a unique identifier type value
- Symbol.for() generates an identifier class value from the incoming value and stores it in the registry as a key
- Symbol.keyfor (), which passes in an identifier type value generated by symbol.for () and returns the value of the key in the registry (symbol.for (‘ value ‘)).
Use parseFloat to avoid js precision conversion problems
(0.1 + 0.2).toFixed(10)
"0.3000000000"
parseFloat((0.1 + 0.2).toFixed(10))
0.3
Copy the code
Easier handwritten call
Function.prototype.myCall = function(context,... args){
context = context || window
const symbol = Symbol()
context[symbol] = this
constresult = context[symbol](... args)delete context[symbol]
return result
}
Copy the code
[].shift.call(arguments)
Change boundthis:let a = [1.2.3]
const myshift = [].shift.bind(a)
console.log(myshift(a))
Copy the code
- [].shifit.call(Arguments) can be converted to an array and can be manipulated
function fn3 (a, b) {
console.log(arguments)
console.log([...arguments])
console.log([].shift.call(arguments))}Copy the code
If the argument passed in is a function, then [].shift.call(arguments) will pop the function
Event broker application
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handwriting function test</title>
</head>
<body>
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('#ul')
ul.addEventListener('click'.(event) = > {
console.log(event.target);
})
</script>
</body>
</html>
Copy the code
Prevents events from bubbling
- Action: Bind stopPropagation to the event execution event of the child DOM node
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handwriting function test</title>
</head>
<body>
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li id="li">4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('#ul')
ul.addEventListener('click'.(event) = > {
console.log(event);
}) // Catch (parent event) and then bubble (child event) if the following configuration item is true
let li = document.querySelector('#li')
li.addEventListener('click'.(event) = > {
console.log(event, '4 clicked ')
event.stopPropagation() // Stop the rest of the capture
})
</script>
</body>
</html>
Copy the code
Configuration that reverses the order of bubbling events and capturing events
- The default false
<div>The outer div<p>The inner p</p>
<div>var div = document.querySelector('div'); var p = document.querySelector('p'); Div. AddEventListener ('click', function() {console.log(" bubble ")}, false); Div. AddEventListener ('click', function() {console.log(" catch ")}, true); Div, output bubble, capture, p, output capture, bubbleCopy the code
What does the browser same-origin policy do, and why cross-domain requests?
- When we use Ajax to submit a request to www.b.com from www.a.com, by default the browser does not allow it because it violates the browser’s same-origin policy.
- Refer to the address: www.cnblogs.com/anai/p/4227…
Cross-domain solutions
- Jsonp
- Cors white list
- Document.domain (same for secondary domain names –>a.test.com and b.test.com)
- postMessage
- Front-end Proxy Forward proxy
- Back-end Proxy Reverse proxy
Cookie, localStorage, sessionStorage difference
- Cookies: More request for the network server through the request in the process of information in the client browser, can be used to save the state of the user login, to circumvent the HTTP request stateless defects, defect is a name value value of the corresponding size is only 4 k, can be storage is too small, more than can be cut, and every request, to carry extra bandwidth
- LocalStorage: unless manually cleared, it is used to exist in localStorage and can be shared under the same origin TAB. It is suitable for some permanent data, such as base64 data of some e-commerce websites, which is about 5 MB in size
- SessionStorage: exists only in the current window, does not share under the same origin tag, the browser window will be automatically cleared after closing, suitable for the website that needs to log in again every time open the token data store JWT. It’s about 5 trillion in size
- SessionStorage saves data for a session in the browser. When the session ends (usually when the window closes), the data is cleared. The special feature of sessionStorage is that even if two pages under the same domain name are not opened in the same browser window, their sessionStorage content cannot be shared. LocalStorage is shared in all origin Windows; Cookies are also shared across all the same origin Windows. The properties and methods of SessionStorage are exactly the same as those of LocalStorage, except for the length of the retention period.
- Reference: github.com/ljianshu/Bl…
Know of any new caching schemes?
-
IndexDB: a NoSQL database provided by the browser that is similar to localStorage and persists unless manually cleared, similar to asynchronous access to MongoDB.
-
Reference: Introduction to Ruan Yifeng IndexDB
-
Reference: Short book IndexDB instance
-
ServiceWorker: address jakearchibald.com/2014/offlin…
-
You can hijack requests and responses, cache them, and run them offline. You cannot define global variables under ServiceWorker
-
Similar webWorker:www.ruanyifeng.com/blog/2018/0 ServiceWorker…
An analysis of how proxies work
- Forward and reverse proxies have advantages and disadvantages
- Proxy Forward proxy principle:
- Proxy Local proxy principle in WebPack
- The express framework is used to build the Web project service, introduced
http-proxy-middleware
Middleware, reference linkswww.jianshu.com/p/8fd5d7347…
The Node service background receives precheck requests to prevent errors
if(res.method == 'OPTIONS') {
res.statusCode = 204
res.setHeader('Content-Length', '0')
res.end()
} else {
next()
}
Copy the code
Browser caching mechanism (back-end)
How browsers render
Reference address: github.com/ljianshu/Bl…
- Receiving information parsing code process:
- Take the HTML file and build the DOM tree
- Take the CSS file and build the CSSOM tree
- Receive the jS file (load the jS script), wait until the Javascript script file is loaded, use the DOM API and CSSOM API to manipulate the DOM Tree and CSS Rule Tree.
- Note: When building the DOM, if the HTML parser encounters JavaScript, it pauses building the DOM, handing control to the JavaScript engine, and when the JavaScript engine finishes running, the browser resumes building the DOM where it left off.
- The browser downloads and builds CSSOM, then executes JavaScript, and finally continues to build the DOM.
- In addition, when operating the style of DOM elements in JS, if you modify multiple styles, it is better to write multiple styles as a class and add class operations to elements. If you are adding element styles step by step, you can assign the element to a variable to avoid retrieving the element more than once, because retrieving the element can also cause backflow.
-
- Instead of changing the DOM style one by one, try to set the class in advance, and then add the class in batches.
-
- Manipulate the DOM in memory using the documentFragment object
-
- It is not necessary to use visibility: hidden to replace display: None. You can use display: None to display elements that have been changed frequently.
RAF discussion
- The screen refreshes every 16.6ms. For example, in one frame a person is standing up, and in the next frame he should take his left leg out. If the next frame has passed, and the browser hasn’t rendered the leg out yet, the person is still standing and looks stuck. Then the Event loop and render side. My understanding is that in just 16.6ms, it is necessary to ensure that a tick can complete and render the DOM operations in that tick (and therefore multiple DOM operations in the same tick will be merged) so that the next frame can have a moving image on the screen. If the current tick takes a long time to execute, say 40ms, then at least two frames are standing and only 10ms is left for the third frame to re-render. If it works, you can see it in the next frame, otherwise you won’t see the change in the next frame.
- So, let’s say that js in a tick goes to something first
-
I added a couple of them
- The child node then has to do a very time-consuming task that takes a long time to complete together. It is better to split the two tasks and execute them in two requestAnimationFrame callbacks so that the DOM changes can be re-rendered first and the next frame will at least see the changes.
# # # front-end security reference: [XSS attacks and CSRF attacks] (https://github.com/dwqs/blog/issues/68) XSS: [https://juejin.cn/post/6844903685122703367](https://juejin.cn/post/6844903685122703367)
CSRF: [https://juejin.cn/post/6844903689702866952#heading-32] (https://juejin.cn/post/6844903689702866952#heading-32)
Understand webpack principle, hand-write small Webpack
Process analysis:reference
- CreateAsset: read the entry file, parse method with Babylon will file content string into the AST syntax tree () contains the id, the filename, dependencies, code information in a data structure
- CreateGraph: Create a new class of dependencies array that looks exactly like the AST dependencies array created by createAsset. Add a mapping attribute to the dependencies array and order them incrementally by their id.
- Bundle: A self-executing function that receives the Graph array and generates the bundle structure
- Code address: github.com/dykily/simp…