JS related
JS prototype and prototype chain
function Person() {} Person.prototype.name = 'Zaxlct'; Person.prototype.sayName = function() { alert(this.name); } var person1 = new Person(); //When JS creates objects, there is a__ proto__ Is used to point to the prototype object of the constructor that created it. //Every object has __ proto__ Property, but only function objects have prototype attribute // object person1 There is one __ proto__ Property and the constructor that creates it is Person, the prototype object of the constructor is Person.prototype console.log(person1.__proto__ == Person.prototype) //true //Of all function objects__ proto__ All point to Function.prototype String.__proto__ === Function.prototype // true String.constructor == Function //true
prototype.jpg
Several ways of JS inheritance
Explain in detail
-
Prototype inheritance
function Parent () { this.name = 'Parent' this.sex = 'boy' } function Child () { this.name = 'child' } // Point the prototype object of the child class to an instance of the parent class Child.prototype = new Parent() //Excellent: inherits the template of the parent class and the prototype object of the parent class //Missing: 1. Cannot implement multiple inheritance (because the prototype object has been specified) // 2. When creating a subclass, you cannot pass parameters to the constructor of the parent class
-
Constructor inheritance
Use call or apply inside the subclass constructor to call the parent constructor and copy the instance properties of the parent class to the subclass.
function Parent (name) { this.name = name } function Child () { //Use. call To change Parent Pointer inside constructor Parent.call(this, 'child') } //Excellent: it solves the problem that the subclass instances of the prototype chain inherit and share the parent class reference object, realizes multi inheritance, and can pass parameters to the parent class when creating subclass instances //Missing: Construction inheritance can only inherit the instance properties and methods of the parent class, not the properties and methods of the parent class prototype
-
Combinatorial inheritance
Composite inheritance is the combination of prototype chain inheritance and constructor inheritance.
-
Prototype chain inheritance is used to ensure that the subclass can inherit the properties and methods in the parent class prototype
-
Construct inheritance is used to ensure that the subclass can inherit the instance properties and methods of the parent class
-
-
Parasitic combinatorial inheritance
-
class inheritance
In class Inheritance mainly depends on two things:
-
extends
-
super
class Parent { constructor (name) { this.name = name } getName () { console.log(this.name) } } class Child extends Parent { constructor (name) { super(name) this.sex = 'boy' } }
Event Loop event loop
Synchronous and asynchronous, macro task and micro task are two different dimensions of function description.
Synchronization tasks refer to tasks queued on the main thread. The next task can be executed only after the previous task is executed; Asynchronous tasks refer to tasks that do not enter the main thread but enter the task queue. The task will enter the main thread for execution only after the main thread task is completed and the task queue starts to notify the main thread and request to execute the task.
After a macro task is executed, it will check whether there is a micro task queue. If yes, execute all tasks in the micro task queue first; If not, the top tasks in the macro task queue will be read in the execution environment stack; When micro tasks are encountered during macro task execution, they are added to the micro task queue in turn. After the stack is empty, read the tasks in the micro task queue again, and so on.
Promise > asynchronous (micro task (process.nextTick, Promises.then, Promise.catch, restore, reject, mutationobserver) > macro task (setTimeout, setInterval, setImmediate))
await blocking The following code executes, so jump out of the async function to execute the next micro task
Promise and Async/Await difference
async/await is implemented based on Promise and looks more like synchronous code,
-
There is no need to write anonymous functions to handle the resolve value of Promise
-
Error handling: Async/Await enables try/catch to handle both synchronous and asynchronous errors.
-
Conditional statements are as concise as error handling
-
Intermediate value processing (the return value of the first method used as the second method parameter) solves the nesting problem
-
Convenient debugging
const makeRequest = () => { try { getJSON().then(result => { // JSON.parse may fail const data = JSON.parse(result) console.log(data) }) // Uncomment to handle asynchronous code errors // .catch((err) => { // console.log(err) // }) } catch (err) { console.log(err) } }
Using aync/await, catch can handle JSON.parse errors:
const makeRequest = async () => { try { // this parse may fail const data = JSON.parse(await getJSON()) console.log(data) } catch (err) { console.log(err) } }
promise how to realize chain call and return different states
Implement chain call: a promise object will be returned after using the. then() or. catch() method. You can continue to call with the. then() method. The parameters obtained by calling again are the contents of the previous then method return
-
The three states of promise are Completed / pending / rejected
-
The status can only be pending -- > fulfilled or pending -- > rejected, and can not be modified again once it is changed;
-
Used in Promise resolve and reject Two functions to change the state;
-
What the then method does internally is state judgment:
-
If the status is success, the success callback function is called
-
If the status is failed, call the failed callback function
Function coritization
Currying It is to transform the original function that receives multiple parameters into a function that accepts a single parameter (the first parameter of the original function) and returns a new function. The new function can accept the remaining parameters and return the same result as the original function.
-
Parameter pair multiplexing
-
Improve practicability
-
Deferred execution only passes part of the parameters of the function to call it and let it return a function to process the remaining parameters. Coriolised functions can delay receiving parameters, that is, for example, a function needs to receive two parameters during execution, otherwise it cannot be executed. However, coriolised functions can receive one parameter first
// Ordinary add function function add(x, y) { return x + y } // After Currying function curryingAdd(x) { return function (y) { return x + y } } add(1, 2) // 3 curryingAdd(1)(2) // 3
JS object deep cloning
Recursively traverse the object to solve the circular reference problem
To solve the circular reference problem, we need a storage container to store the corresponding relationship between the current object and the copied object (suitable for storing with the key value data structure, that is, map) , when copying the current object, we first find out whether the storage container has copied the current object. If it has been copied, it will be returned directly. If not, it will continue to copy.
function deepClone(target) { const map = new Map() function clone (target) { if (isObject(target)) { let cloneTarget = isArray(target) ? [] : {}; if (map.get(target)) { return map.get(target) } map.set(target,cloneTarget) for (const key in target) { cloneTarget[key] = clone(target[key]); } return cloneTarget; } else { return target; } } return clone(target) };
JS modularization
The modules in nodeJS are implemented based on the commonJS specification. The principle is to read and write files. Exports and module.exports are used for exporting files, and require is used for importing files. Each file is a module; the code in each file will be written in a closure function by default. Amd specification is an asynchronous loading module, which allows you to specify callback functions, AMD yes RequireJS The standardized output of module definition in the promotion process.
AMD advocates relying on the front, CMD advocates dependency. For dependent modules, AMD executes in advance and CMD executes in delay.
In ES6, we can use import Keyword introduction module, through exprot Keyword export module, but ES6 cannot be executed in the browser at present, so we can only compile unsupported import into widely supported one through babel require.
Differences between CommonJs and ES6 modularity:
-
The CommonJS module outputs a copy of the value, and the ES6 module outputs a reference to the value.
-
CommonJS module is loaded at run time, and ES6 module is the output interface at compile time.
Front end Modularization: CommonJS,AMD,CMD,ES6
The difference between import and require import
ES6 standard module of import; require is the introduction method of AMD specification;
import is called at compile time, so it must be placed at the beginning of the file; It is a deconstruction process, and require is a runtime call, so require can theoretically be used anywhere in the code; Is the assignment process. In fact, the result of require is an object, number, string, function, etc., and then assign the result of require to a variable
Asynchronous loading JS mode
-
Anonymous function self-tuning dynamic creation of script tag loading js
(function(){ var scriptEle = document.createElement("script"); scriptEle.type = "text/javasctipt"; scriptEle.async = true; scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js"; var x = document.getElementsByTagName("head")[0]; x.insertBefore(scriptEle, x.firstChild); })();
-
async attribute
// The async attribute specifies that the load script will execute asynchronously once it is available <script type="text/javascript" src="xxx.js" async="async"></script>
-
defer attribute
// The defer attribute specifies whether script execution is delayed until the page is loaded <script type="text/javascript" src="xxx.js" defer="defer"></script>
Set,Map,WeakSet,WeakMap
The Set object can store any type of data. The value is unique and there are no duplicate values.
A Map object stores key value pairs, and any value can become its key or value.
WeakSet Structure and Set Similarly, it is also a collection of non repeated values WeakMap An object is a collection of key value pairs
Different: WeakSet Members of can only be objects, not values of other types. WeakSet is not traversable.
WeakMap only accepts objects as key names (except null), and does not accept other types of values as key names.
The object pointed to by the key name of the WeakMap is not included in the garbage collection mechanism.
call,apply
call( this,a,b,c ) After the first parameter, all subsequent parameters are the values passed into the function. apply( this,[a,b,c] ) There are only two parameters. The first is an object and the second is an array. This array is the parameter of the function.
Common: they can be used to call a method instead of another object, and change the object context of a function from the initial context to the new object specified by thisObj.
The so-called anti shake means that the function can only be executed once in n seconds after triggering the event. The so-called throttling means that the function can only be executed once in n seconds after continuously triggering the event.
What is the third parameter of addEventListener? It is captured when it is true and bubbles when it is false
Object.prototype.toString.call() Judge object type
// new Set is to implement array de duplication, // Array.from() converts the de duplication into an array let arr2 = Array.from(new Set(arr));
Lexical scope and scope chain
The scope specifies how to find variables, that is, to determine the access rights of the currently executing code to variables.
ES5 only has global scope and function scope, while ES6 adds block level scope
Temporary deadband: within a code block, use let and const Before the command declares a variable, the variable is unavailable, which is called a temporary deadband in syntax.
JavaScript uses lexical scope, that is, static scope.
The scope of a function is determined when the function is defined.
When searching for a variable, you will first search from the variable object of the current context. If it is not found, you will always find the variable object of the global context, that is, the global object, from the variable object of the parent execution context on the lexical level. In this way, the linked list composed of variable objects of multiple execution contexts is called the scope chain.
The new keyword does four things:
function _new(constructor, ...arg) { // Create an empty object var obj = {}; // The ` _proto ` of the empty object points to the ` prototype 'of the constructor, Add properties for this new object obj.__proto__ = constructor.prototype; // The scope of the constructor is assigned to the new object var res = constructor.apply(obj, arg); // Returns a new object. If there is no explicit return statement, this is returned return Object.prototype.toString.call(res) === '[object Object]' ? res : obj; }
Arrow functions should not be used in some cases:
-
When you want the function to be promoted (the arrow function is anonymous)
-
When you want to use this/arguments in a function, because the arrow functions themselves do not have this/arguments, they depend on the external context
-
Use named functions (arrow functions are anonymous)
-
When using function as constructor (arrow function has no constructor)
-
When you want to add a function as a property and use the object in it, because we can't access it this The object itself.
Four methods of judging arrays
-
Array.isArray() judge
-
instanceof Judgment: check whether the prototype attribute of the constructor appears in the prototype chain of the object and return a Boolean value. let a = []; a instanceof Array; //true
-
Constructor judgment: constructor attribute of the instance points to constructor let a = [1,3,4]; a.constructor === Array;//true
-
Object.prototype.toString.call() Judge let a = [1,2,3]; object. Prototype. ToString. Call (a) = = '[object array]'; / / true
What are the advantages of TS
-
Static input: static typing is a feature that detects errors when developers write scripts.
-
Large development projects: Refactoring with TypeScript tools becomes easier and faster.
-
Better collaboration: type safety is about detecting errors during coding, not when compiling a project.
-
Greater productivity: clean ECMAScript 6 code, automatic completion and dynamic input help to improve the efficiency of developers.
Difference between interface and type
-
interface can only define object types. Type declarations can declare any type.
-
interface can declare merging, and two identical interfaces will merge. Type declaration merging will report an error
-
Type can be derived from type
Frame Vue React
What's new in Vue3.0
Bidirectional data binding Proxy
Proxy can be understood as setting an "interception" before an object. When the object is accessed, it must go through this layer of interception. This means that you can perform various operations in this layer of interception. For example, you can process the original object in this layer of interception and return the data structure you want to return.
ES6 natively provides a Proxy constructor, which is interpreted on the MDN as: the Proxy object is used to define the user-defined behavior of basic operations (such as attribute search, assignment, enumeration, function call, etc.).
const p = new Proxy(target, handler); //target: The target object to intercept (can be any type of object, including a native array, a function, or even another proxy) //handler: an object that defines the behavior to be intercepted const p = new Proxy({}, { get(target, propKey) { return 'Ha ha, you were intercepted by me'; } }); console.log(p.name);
For the new attributes, there is no need to add reactive processing again, because Proxy is an operation on an object. As long as you access the object, you will go to the logic of Proxy.
Vue3 Composition API
Vue3.x Composition API setup was introduced It is the entry to use the composition API in the component. Setup When is the execution time beforeCreate Execute before
reactive, ref and toRefs, isRef
Vue3.x can use reactive and ref for data definition.
// props Pass in component pair properties // context A context object that contains some useful attributes: attrs,parent,refs setup(props, context) { // ref Define data const year = ref(0); // reactive Handle bidirectional binding of objects const user = reactive({ nickname: "xiaofan", age: 26, gender: "female" }); setInterval(() => { year.value++; user.age++; }, 1000); return { year, // Using toRefs, the structure is deconstructed ...toRefs(user), }; }, // isRef is provided to check whether an object is a ref object
watchEffect listener function
-
watchEffect does not need to manually pass in dependencies
-
watchEffect is executed once to automatically collect dependencies
-
watchEffect cannot get the value before the change, but only the value after the change
computed can pass in get and set
Defines the calculation properties that can be changed
const plusOne = computed({ get: () => count.value + 1, set: val => { count.value = val - 1 } });
Using TypeScript and JSX
Setup now supports the return of a rendering function, which returns a JSX. JSX can directly use the reactive state declared in the setup scope:
export default { setup() { const count = ref(0); return () => (<div>{count.value}</div>); }, };
Vue versus React?
Similarities:
-
Both have Virtual DOM (Virtual DOM is a JavaScript object that maps to the real DOM)
-
Both provide responsive and componentized view components.
Differences: Vue is an MVVM framework with two-way data binding. When the ViewModel updates the Model, it updates to the View through data binding.
React is a one-way data flow library with state driven view. State --> View --> New State --> New View ui = render (data)
Templates render differently. React renders templates through JSX, while Vue renders templates through extended HTML.
Component forms are different. Vue files combine HTML, JS and CSS. react provides class components and function groups
Vue encapsulates some v-if, v-for and React, which are implemented by itself with a higher degree of freedom
Vue initialization process, bidirectional data binding principle
vue.js uses data hijacking combined with publisher subscriber mode to hijack setter s, getter s and dep.addSub of various properties through Object.defineProperty() to collect subscription dependencies. The watcher monitors data changes and publishes messages to subscribers when data changes, triggering corresponding monitoring callbacks.
The listener Observer is used to hijack and listen to all properties. If there is any change, it will notify the subscriber. The subscriber Watcher can receive the change notification of the attribute and execute the corresponding function, so as to call the corresponding update to update the view.
v-model Command, which can easily realize the two-way binding between form input and application state.
computed: Caching is supported. Recalculation will be performed only when the dependent data result changes. Asynchronous operation is not supported. If an attribute depends on other attributes, many to one, usually calculated
watch: When the data changes, the corresponding operation is triggered directly. Asynchronous is supported. The listening data must be the data in props declared in data or passed by the parent component. When the data changes, other operations are triggered. The function has two parameters
Implementation principle of Vue router
The core of the introduction of end-to-end routing and the implementation principle of Vue router is to update the view without re requesting the page. Switching between paths, that is, switching between components. Vue router implements single page route jump mode: hash mode and history mode. Set the mode parameter as required
hash mode: render different data of the specified DOM position according to different values through the change of anchor value. Each time # after the change, a record will be added to the browser's access history. Use the "back" button to return to the previous position. History mode: Using window.history.pushState API to complete URL jump without reloading the page.
Implementation principle of vuex:
Vue.use(vuex) calls vuex's install method
Before the beforeCreate hook, the vuexInit method is mixed in. The vuexInit method implements store injection into the vue component instance and registers vuex The reference property $store of the store.
The state state of Vuex is a response form, which stores the state in the data of vue instance component with the help of vue's data;
Vuex's getters realize real-time data monitoring with the help of vue's calculated attribute.
The principle and operation mechanism of nextTick?
nextTick source code analysis
When Vue updates the DOM, it also calls nextTick internally for asynchronous queue control. Whenever data changes are observed, Vue will open a queue and buffer all data changes that occur in the same event loop. If the same watcher is triggered multiple times, it will only be pushed into the queue once.
DOM will at least update the view uniformly after all data changes in the current event loop are completed. When we call nextTick ourselves, it adds our own callback function after updating the microtask (micro task queue) of the dom,
This ensures that our code is executed after the DOM is updated, and avoids the possible multiple execution problems of setTimeout. Ensure that the micro tasks in the queue are executed before an event loop.
Vue implements a high-level component
A higher-order component is a function that takes a component as a parameter and returns a new component. Dynamically add some additional properties or behaviors to the object during program operation without changing the object itself.
// Received by higher order component (HOC) props It should be transmitted to the packaged component, that is, the original component prop should be directly transmitted to the packaged component // High level components can be added, deleted and modified props export default function Console(BaseComponent) { return { props: BaseComponent.props, mounted() { console.log("High order component"); }, render(h) { console.log(this); // take this.$slots Format as array because h The third parameter of the function is the child node, which is an array const slots = Object.keys(this.$slots) .reduce((arr, key) => arr.concat(this.$slots[key]), []) .map((vnode) => { vnode.context = this._self; // Binding to high-level components, vm: solve the problem that named slots are rendered as default slots return vnode; }); // Transparent props, transparent events, transparent slots return h( BaseComponent, { on: this.$listeners, attrs: this.$attrs, // attrs Refers to those that are not declared as props Properties of props: this.$props, }, slots ); }, }; }
Vue.component(),Vue.use(),this.$xxx()
The Vue.component() method registers global components.
-
The first parameter is the user-defined element name, that is, the label name of this component to be used in other components in the future.
-
The second parameter is the Vue component to be registered.
import Vue from 'vue'; // Introducing the loading component import Loading from './loading.vue'; // Register loading as a global component and use the loading component in other components through the < loading > tag Vue.component('loading', Loading);
Vue.use registers the plug-in, which receives a parameter. This parameter must have an install method. The vue.use function calls the install method of the parameter internally.
-
If the plug-in has not been registered, an installed attribute will be added to the plug-in after successful registration, with the value of true. The Vue.use method internally detects the installed attribute of the plug-in to avoid repeated registration of the plug-in.
-
The plug-in's install method will receive two parameters. The first parameter is Vue and the second parameter is the configuration item options.
-
You can add global methods or properties inside the install method
import Vue from 'vue'; // This plug-in must have the install method const plugin = { install (Vue, options) { // Add global method or attribute Vue.myGlobMethod = function () {}; // Add global directive Vue.directive(); // Add blend Vue.mixin(); // Add instance method Vue.prototype.$xxx = function () {}; // Register global components Vue.component() } } // Vue.use will call the install method of plugin internally Vue.use(plugin);
Mount the Hello method on Vue's prototype
import Vue from 'vue'; import Hello from './hello.js'; Vue.prototype.$hello = Hello;
this.$hello('hello world ') can be found in the vue component
Vue parent component transfers props data, and child component modifies parameters
-
When a parent-child component passes values, the parameters, arrays and objects passed by the parent component can be modified directly after the child component accepts them, and the corresponding values of the parent component will also be modified. A warning is issued in the console.
-
If the passed value is a string, an error will be reported if you modify it directly. One way data flow. Every time the parent component is updated, all prop s in the child component will be refreshed to the latest value.
If the sub component wants to modify the data in prop:
-
Define a local variable and assign a value using the value of prop
-
Define a calculation property, process the value of prop and return
Vue parent-child component lifecycle execution sequence
Load Render Pass
Parent beforecreate - > parent created - > parent beforemount - > child beforecreate - > child created - > child beforemount - > child mounted - > parent mounted
Sub component update process
Parent BeforeUpdate - > child BeforeUpdate - > child updated - > parent updated
Parent component update process
Parent BeforeUpdate - > parent updated
Destruction process
Parent beforedestroy - > child beforedestroy - > child destroyed - > parent destroyed
Vue custom directives
The custom instruction provides several hook functions: bind: called when the instruction is bound to the element for the first time, inserted: called when the bound element is inserted into the parent node, update: called when the VNode of the component is updated
After using slot, you can display the inserted new label in the subcomponent
webpack and Engineering
The life cycle of webpack, and hooks
Compiler (entire lifecycle [k) ə m ˈ pa ɪ l ə r] ) hook https://webpack.docschina.org/api/compiler-hooks/compilation (compile)[ ˌ k ɑː mp ɪˈ le ɪʃ n] ) hook
The compiler object contains all the configuration information of the webpack environment. This object is created at one time when starting the webpack, and all operable settings are configured, including options, loader and plugin. When a plug-in is applied in a webpack environment, the plug-in will receive a reference to the compiler object. You can use it to access the main environment of webpack.
The compilation object contains the current module resources, compilation generated resources, changed files, etc. When running the webpack development environment middleware, whenever a file change is detected, a new compilation will be created to generate a new set of compilation resources. The compilation object also provides many callbacks at critical times for the plug-in to choose when doing custom processing.
compiler represents the whole lifecycle of webpack from Startup to shutdown It just represents a new compilation process
webpack compilation process
The compilation process of Webpack is a serial process. The following processes will be executed from start to end:
-
Initialization parameters: read and merge parameters from configuration files and Shell statements to get the final parameters;
-
Start compilation: initialize with the parameters obtained in the previous step Compiler Object, load all configured plug-ins, and execute object The run method starts compiling;
-
Determine entry: according to the in the configuration entry Find all the entry files;
-
Compilation module: starting from the entry file, call all configured modules Loader Translate the module, find out the module that the module depends on, and then recurse this step until all the files that the entry depends on have been processed in this step;
-
Complete module compilation: use after step 4 Loader After translating all modules, the final translated content of each module and the dependencies between them are obtained;
-
Output resources: according to the dependencies between entries and modules, they are assembled into chunks containing multiple modules, and then each Chunk Convert to a separate file and add it to the output list. This step is the last chance to modify the output content;
-
Output completion: after determining the output content, determine the output path and file name according to the configuration, and write the file content to the file system.
Optimize the webpack packaging and compilation process of the project
1. Build management: during the build process, each Loader and Plugin The execution time of is consumed on the Loader compiling JS and CSS and the plugin performing compression operation on these two types of code. A tool: speed measure webpack plugin
2. Cache: most loaders provide cache Configuration item. cache-loader , Write the compilation result of loader to the hard disk cache
3. Multi core compilation. The happypack project is connected to multi-core compilation, which is understood as happypack Fill all threads with compilation work
4. Pull out, webpack DLL plugin These static dependencies are extracted from each build logic, and the static dependencies are packaged separately. Externals removes the static resources that do not need to be packaged from the build logic and uses CDN references
5. Although tree shaking relies on a certain module, it only uses some of its functions. adopt Tree shaking, eliminate unused modules to achieve the purpose of deleting useless code.
First screen loading optimization
Lazy loading of routes: instead, import is used as a reference, which is dynamically introduced in the form of a function. You can package the respective route files. Only when a given route is parsed can the route components be downloaded;
Element UI load on demand: reference the components actually used;
Repeated packaging of components: the Commons chunkplugin configuration is used to unpack the packages. The packages that have been used twice or more are extracted and put into the public dependency file. There are reusable components on the home page, and the public dependency file will also be downloaded;
Gzip: after unpacking, use gzip to compress and close the sourcemap.
UglifyJsPlugin: Production environment, compress obfuscated code and remove console code
CDN deployment of static resources: when the static request is made in nginx, the address of the static resources will be obtained to redirect the CDN content distribution network
For the first screen loading of the mobile terminal, the skeleton screen can be used, the loading can be customized, and the front page can be rendered on the service terminal separately.
How to optimize front-end performance (21 optimizations + 7 positioning modes)
Web pack hot update mechanism
Hot update process summary:
-
Start the local server so that the browser can request local static resources
-
After the page is opened for the first time, the server and the client establish a communication channel through websocket to return the next hash to the front end
-
The client obtains the hash, which will be used as the hash of the next request to the server for hot-update.js and hot-update.json
-
After modifying the page code, Webpack listens to the file modification and starts compiling. After compiling, it sends a build message to the client
-
After the client obtains the hash, the client constructs a hot-update.js script link and inserts it into the main document
-
After the hot-update.js is successfully inserted, execute the createRecord and reload methods of the hotAPI, obtain the render method of the Vue component, re render the component, and then update the UI without refresh.
webpack loader and plugin are introduced. The difference between CSS loader and style loader
loader It is A converter that compiles A file to form B file,
plugin , It is an extender to operate files. It is aimed at the whole process of webpack packaging after the loader is completed. It does not directly operate files. It will listen to some nodes (run, build module, program) in the process of webpack packaging
Babel It can convert the ES6/ES7 code into the code that the specified browser can support.
css-loader The function of style loader is to transcode CSS files: use < style > to inject CSS loader internal styles into our HTML pages
First use CSS loader transcodes and then uses it Insert style loader into file
How to write a webpack plugin?
https://segmentfault.com/a/1190000037513682
Composition of webpack plug-in:
-
A JS named function or a class (think about the plug-ins we usually use) new XXXPlugin())
-
Define an apply method on the prototype of the plug-in class / function.
-
Pass in the compiler in the apply function and insert the specified event hook to get the compilation object in the hook callback
-
Process specific instance data inside the webpack through compilation
-
If the plug-in is asynchronous, after the logic of the plug-in is written, call the callback provided by webpack.
Why did Vite start so fast
Webpack will package first, then start the development server, and directly give the packaging results when requesting the server.
Vite directly starts the development server and requests which module to compile the module in real time.
Vite takes the module files in the development environment as the files to be executed by the browser, rather than packaging and merging them like Webpack.
Since Vite does not need to be packaged at startup, it means that there is no need to analyze module dependencies and compile. Therefore, the startup speed is very fast. When the browser requests a module, it compiles the module content as needed.
How is your scaffold made
use download-git-repo Download the warehouse code democommander: complete node.js Command line solution. Declare the program using. option() Method to define the option Inquirer.js: a collection of command-line user interfaces.
Front end monitoring
Front end monitoring usually includes behavior monitoring (PV/UV, buried point interface statistics), anomaly monitoring and performance monitoring.
A monitoring system can be roughly divided into four stages: log collection, log storage, statistics and analysis, reporting and warning.
Error monitoring
Vue special error warning method Vue.config.errorHandler, (Vue provides functions that can only capture the page life cycle, such as created and mounted)
Vue.config.errorHandler = function (err) { console.error('Vue.error',err.stack) // Logical processing };
Framework: betterjs, fundebug (charge) the script for capturing errors should be placed at the front to ensure that error information can be collected. Methods:
-
Window. Oneror() when js runtime error triggers, oneror can accept multiple parameters (message, source, lineno, colno, error).
-
window.addEventListener('error'), function(e) {}, true It will be triggered before window.oneror. It cannot prevent the execution of the default event handler function, but it can catch the error of resource loading exception globally
Front end JS error capture -- sourceMap
How to monitor web page crashes** What's the difference between collapse and carton** Monitoring error
-
The Service Worker has its own independent working thread, which is different from the web page. When the web page crashes, the Service Worker will not crash under normal circumstances;
-
The life cycle of service workers is generally longer than that of web pages, which can be used to monitor the status of web pages;
Caton: rendering is blocked while loading
Performance monitoring & & Performance Optimization
Performance index:
-
FP (first drawing)
-
FCP (First contentful paint)
-
LCP (maximum content paint time)
-
FPS (frames transmitted per second)
-
TTI (page interactive Time to Interactive)
-
HTTP Request response time
-
DNS Resolution time
-
TCP Connection time
Performance data collection requires window.performance API , JS Library web-vitals: import {getLCP} from 'web-vitals';
// Redirection time redirect: timing.redirectEnd - timing.redirectStart, // DOM Rendering time dom: timing.domComplete - timing.domLoading, // Page load time load: timing.loadEventEnd - timing.navigationStart, // Page unload time unload: timing.unloadEventEnd - timing.unloadEventStart, // Request time request: timing.responseEnd - timing.requestStart, // Current time when getting performance information time: new Date().getTime(), // DNS query time consuming domainLookupEnd - domainLookupStart // TCP link time consuming connectEnd - connectStart // request time consuming responseEnd - responseStart // Parsing dom trees takes time domComplete - domInteractive // White screen time domloadng - fetchStart // onload time loadEventEnd - fetchStart
Common means of performance optimization: caching technology Preloading technology Rendering scheme.
-
cache : It mainly includes cdn, browser cache, local cache and application offline package
-
Preload : prefetch is another performance optimization technique. Pre fetching can tell browser users what resources they may use in the future.
-
prefetch supports pre fetching images, scripts or any resources that can be cached by the browser.
Add in head < linkrel="prefetch"href="image.png">
-
prerender is a heavyweight option that allows the browser to load all resources of a specified page in advance.
-
subresource can be used to specify that resources have the highest priority. The current page needs or will be used soon.
-
Rendering scheme:
-
Static rendering (SR)
-
Front end rendering (CSR)
-
Server side rendering (SSR)
-
Client side rendering (NSR): NSR data request, first screen data request and data online are paralleled with an initialization framework of webview and JS initialization, which greatly shortens the first screen time.
-
640.png
Six common design patterns and application scenarios
https://www.cnblogs.com/whu-2017/p/9471670.html
The concept of observer model
Observer mode is a kind of behavioral mode. It defines a one to many dependency, allowing multiple observer objects to listen to a topic object at the same time. When the state of this subject object changes, it will notify all observer objects.
Concept of publishing subscriber pattern
In the publish subscribe mode, the sender of a message is called publishers, and the message will not be sent directly to a specific receiver, called subscribers. It means that publishers and subscribers do not know each other's existence. A third-party component, called information mediation, is needed. It connects subscribers and publishers. It filters and distributes all incoming messages. In other words, the publish subscribe model is used to handle the exchange of information between different system components, even if these components do not know each other's existence.
You need a third-party component, called information mediation, that connects subscribers and publishers
Factory mode It mainly provides an interface for creating objects. Scenario: it is impossible to foresee what kind of instances need to be created during coding.
Agent mode command mode
Singleton mode
Ensure that a class has only one instance and provide a global access point to access it. (window)
Http and browser related
Seven layer network model
Application layer, presentation layer, session layer, transport layer, network layer, data link layer and physical layer
TCP: connection oriented, reliable transmission (ensuring data correctness and data order), used to transmit a large amount of data (stream mode), slow speed, and requires a lot of overhead (time and system resources) to establish a connection. (application scenario: HTP, HTTP, mail)
UDP: non connection oriented, unreliable transmission, used to transmit a small amount of data (packet mode), fast speed and possible packet loss (application scenario: instant messaging)
Connected Connection oriented Non connection oriented Transmission reliability reliable unreliable Application occasion A small amount of data Transmit large amounts of data
https
The client first asks the server for the public key, and then encrypts the information with the public key. After the server receives the ciphertext, it decrypts it with its own private key. The server public key is placed in the digital certificate.
url to load the whole process of rendering
-
DNS domain name resolution.
-
TCP shakes hands three times to establish connection.
-
Send HTTP request message.
-
The server processes the request and returns the response message.
-
The browser parses the rendered page.
-
Wave four times and disconnect.
The DNS protocol provides the ability to find IP addresses through domain names, or vice versa IP address anti query domain name service. DNS is a network server. Our domain name resolution is simply to record an information record on DNS.
TCP handshakes three times and waves four times: handshakes and waves are initiated by the client, and the client ends. Three handshakes and four waves
Load balancing: before entering the real application server, the request may pass through the machine responsible for load balancing. Its function is to reasonably distribute the request to multiple servers and forward HTTP requests; At the same time, it has anti attack and other functions. It can be divided into DNS load balancing, HTTP load balancing, IP load balancing, link layer load balancing, etc.
Web Server: after the previous load balancing, the request will enter the Web Server on the corresponding server, such as Apache,Tomcat
Reverse proxy works on HTTP, generally Nginx. Visiting baidu.com all over the country must be accessed through an agent. It is impossible to visit Baidu's server. (VPN forward proxy, proxy client)
Browser parsing and rendering process: after the returned html is transferred to the browser, if there is gzip, it will be decompressed first to find out the file coding format. The HTML loaded by the external chain resources will be parsed from top to bottom. In case of js, CSS will stop parsing and rendering until js execution is completed. Parse HTML, build DOM tree, parse CSS, generate CSS rule tree, merge DOM tree and CSS rules, and generate render tree to render
The behavior of changing the DOM tree, page layout, and element style is called redrawing
The behavior that causes changes in DOM tree structure and page layout is called reflow
GUI rendering thread is responsible for rendering HTML elements of browser interface. When the interface needs Repaint Or caused by some operation Reflow When, the thread executes. When the JavaScript engine runs the script, the GUI rendering thread is suspended, that is, it is "frozen". It will not be executed until the JS program is completed. Therefore, if JS is executed for too long, the rendering of the page will be inconsistent, resulting in the feeling of page rendering loading blocking. JavaScript can manipulate DOM. If the interface is rendered while modifying these element attributes, the element data may be inconsistent before and after rendering
GPU draws multi process browsers: master process, plug-in process, GPU, tab page (browser kernel) multi-threaded browser kernel: each tab page can be regarded as a browser kernel process, and then the process is multi-threaded.
It has several types of sub threads:
-
GUI thread
-
JS engine thread
-
Event triggered thread
-
Timer thread
-
HTTP request thread
http1 and HTTP2
http2
Multiplexing: multiple requests with the same domain name share the same TCP connection, reducing latency
Request priority: set the priority for each request
Binary transmission; It was transmitted in plain text
Data flow: packets are not sent in sequence, and packets are marked. All packets of each request or response become a data stream,
Server push: you can actively send messages to the client.
Header compression: reduce the size and number of packets
If a request is blocked in the pipeline transmission in HTTP/1.1, all requests behind the queue are blocked. HTTP/2 multiple requests reuse a TCP connection. Once packet loss occurs, all HTTP requests will be blocked. HTTP/3 changed the TCP protocol under HTTP to UDP! http1 keep alive serial transmission
What is the role of keep alive in http
Set in response header keep-alive You can send multiple http over a TCP connection request
Browser cache policy
Strong cache: cache control; no-cache max-age=<10000000>; expires; The priority of cache control is higher than expires;
The fields controlling forced caching are Expires and cache control respectively. If the time of the client is less than the value of Expires, the cached results will be used directly.
Negotiation cache: last modified / if modified since and Etag / if none match. The priority of Etag / if none match is higher than that of last modified / first request. The server will add the last modified field in the returned response header to indicate the last modified time of the resource.
When the browser requests again, the if modified since field will be brought in the request header. If the two fields are the same, it proves that the resource has not been modified and returns 304. Otherwise, it returns the resource again with the status code of 200;
Garbage collection mechanism:
Mark clearing: variables entering the execution environment are marked, and then after execution, these marks and variables are cleared. Check whether the variable is referenced.
Reference count: the number of times each value is referenced will be recorded. When the number of references becomes 0, it will be released.
Front end security
Homology strategy: if the protocol, domain name and port of two URL s are the same, we call them homologous. Because the browser has cookies.
-
XSS: cross site scripting input, textarea and other areas where text information may be input, input < script SRC = "http: / / malicious website" > < / script >, and the submitted information will be stored in the server.
-
CSRF: Cross Site Request Forgery. Entice users to open the hacker's website. In the hacker's website, cross site requests are initiated by using the user's login status.
SRC of img of site A = the request interface of site B, which can be accessed; Solution: the referer carries the request source
After accessing the page, the form is submitted automatically, simulating a post operation and sending a post request
Solution: the back end injects a random string into the Cookie, and the front end requests to take out the random string and add it to the back end.
-
http hijacking: hijacking by telecom operators
-
SQL injection
-
Click hijacking: entice the user to click the seemingly harmless button (actually click the transparent button) Button in iframe), add a field to the back-end request header X-Frame-Options
-
File upload vulnerability : The server did not verify the uploaded file
CSS and HTML
What are BFC (block level formatting context), IFC (inline formatting context), FFC (elastic box model)
BFC (Block formatting context), i.e. block level formatting context, is an independent rendering area on the HTML page. Only the elements in the area participate in the rendering and will not affect its external elements. In short, BFC can be regarded as a "Besieged City". External elements cannot enter and internal elements cannot go out (do not interfere with each other).
A container that determines how to render elements. Rendering rules:
-
1. The internal block level elements are placed vertically, one by one.
-
2. The vertical distance of block level elements is determined by margin. The margins of two adjacent block level elements belonging to the same BFC will overlap.
-
3. For left to right formatting, the left edge of each element (block level element and inline element) contacts the left edge of the containing block (the opposite for right to left formatting). This is true even if there is a float in the elements in the containing block, unless the elements in it regenerate into a BFC.
-
4. The area of the BFC does not overlap the floating element.
-
5. BFC is an isolated independent container. The child elements inside the container and the elements outside the container do not affect each other.
-
6. When calculating the height of BFC container, floating elements also participate in the calculation.
Conditions for forming BFC:
1. Floating elements, float values other than none;
2. position (absolute, fixed);
3. display is one of the following values: inline block, table cell, table caption;
4. overflow values other than visible (hidden, auto, scroll);
BFC is generally used to solve the following problems
-
Margin overlap problem
-
Eliminate floating problems
-
Adaptive layout problem
flex: 0 1 auto; What do you mean?
The element is sized according to its width and height. It shortens itself to adapt flex Container, but does not elongate and absorb flex Additional free space in the container to accommodate flex container . The horizontal main axis and vertical cross axis attributes determine which axis to arrange
-
flex-grow: 0 A unitless number (): it will be treated as the value of < flex growth >.
-
flex-shrink: one A valid * * width * * value: it will be treated as < The value of flex basis >.
-
flex-basis: auto Keyword none, auto, or initial
Zoom in, zoom out, and the spindle space occupied before allocating excess space.
Avoid CSS global pollution
-
scoped attribute
-
css in js
const styles = { bar: { backgroundColor: '#000' } } const example = (props)=>{ <div style={styles.bar} /> }
-
CSS Modules
-
Use less to minimize the use of global pair selectors
// Remember to write on the selector so as not to pollute all the li below ul ul{ >li{ color: red; } }
CSS Modules
Ruan Yifeng CSS Modules
CSS Modules is a process in a build step. The process of building tools to make the specified class reach the scope.
CSS Modules It is allowed to declare a global rule using the syntax of:: global(.className). Any class declared in this way will not be compiled into hash string local(className): handle the localIdentName rule and compile the unique hash class name.
CSS Modules features:
-
Instead of using a selector, use only the class name to define the style
-
Instead of cascading multiple classes, use only one class to define all styles
-
Do not nest class es
Box model and box-sizing attribute
width: 160px; padding: 20px; border: 8px solid orange; Standard box sizing: content-box; Total width of element = 160 + 202 + 82; IE Border box: total width 160
When margin/padding takes the value of percentage, it is based on the width and height of the parent element.
css drawing triangle
-
Processing by border
// border handle .class { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid red; } // Width height + border div { width: 50px; height: 50px; border: 2px solid orange; }
-
Clip path clipping
div{ clip-path: polygon(0 100%, 50% 0, 100% 100%); }
-
Implementation of gradient linear gradient
div { width: 200px; height: 200px; background:linear-gradient(to bottom right, #fff 0%, #fff 49.9%, rgba(148,88,255,1) 50%,rgba(185,88,255,1) 100%); }
How to add shadows to triangles after CSS implements triangles
???
N implementations of CSS two column layout
Two column layouts are divided into two types, one is fixed width on the left and adaptive on the right, and the other is adaptive on both columns (that is, the width on the left is determined by sub elements, and the remaining space is supplemented on the right).
-
How to realize left fixed width and right adaptation
// Both elements set dislpay: inline block .left { display: inline-block; width: 100px; height: 200px; background-color: red; vertical-align: top; } .right { display: inline-block; width: calc(100% - 100px); height: 400px; background-color: blue; vertical-align: top; } // The two elements are set to float, and the adaptive element width on the right is calculated using the calc function .left{ float: left; width: 100px; height: 200px; background-color: red; } .right{ float: left; width: calc(100% - 100px); height: 400px; background-color: blue; } // The parent element is set to display: flex, and the adaptive element is set to flex: 1 .box{ height: 600px; width: 100%; display: flex; } .left{ width: 100px; height: 200px; background-color: red; } .right{ flex: 1; height: 400px; background-color: blue; } // The parent element is relatively positioned, the left element is absolutely positioned, and the margin left value set for the right adaptive element is greater than the width of the fixed width element .left{ position: absolute; width: 100px; height: 200px; background-color: red; } .right{ margin-left: 100px; height: 400px; background-color: blue; }
-
The left and right elements are adaptive
// flex layout ditto // Set display: grid for parent element; grid-template-columns:auto 1fr; (this attribute defines the column width. The auto keyword indicates that the length is determined by the browser itself. FR is a relative size unit, indicating that the remaining space is divided equally.) grid gap: 20px (row spacing) .parent{ display:grid; grid-template-columns:auto 1fr; grid-gap:20px } .left{ background-color: red; height: 200px; } .right{ height:300px; background-color: blue; } // Float + BFC The parent element is set to overflow:hidden, the left fixed width element is floating, and the right adaptive element is set to overflow:auto to create BFC .box{ height: 600px; width: 100%; overflow: hidden; } .left{ float: left; width: 100px; height: 200px; background-color: red; } .right{ overflow: auto; height: 400px; background-color: blue; }
CSS three column layout
-
Float layout: left float, right float, middle margin: 0 100px;
-
Position layout: left: 0; Right: 0; Middle left: 100px; right: 100px;
-
Table layout: parent element display: table; Left and right width: 100px; Three elements display: table cell;
-
Flexible layout: parent element display: flex; Left and right width: 100px;
-
Grid layout:
// Gird provides The gird template columns and grid template rows properties let us set the height and width of rows and columns .div{ width: 100%; display: grid; grid-template-rows: 100px; grid-template-columns: 300px auto 300px; }
Common scenarios and problems
How do app and H5 communicate and interact?
// Compatible with IOS and Android callMobile(parameters,messageHandlerName) { //handlerInterface is injected from iOS addScriptMessageHandler and andorid addjavascript interface code. if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { // alert('ios') window.webkit.messageHandlers[messageHandlerName].postMessage(JSON.stringify(parameters)) } else { // alert('android ') //Android can't transfer js json object, only string can be transferred window.webkit[messageHandlerName](JSON.stringify(parameters)) } }
app injects native methods into window for js to call
messageHandlerName Agreed communication method parameters Parameters to be passed in
Mobile terminal adaptation scheme
rem is the font size relative to the root element of HTML and em relative to the parent element. VW,VH High score ratio of screen width to height
//Calculated according to the width diagram, 1rem = 100px; (function (win, doc) { function changeSize() { doc.documentElement.style.fontSize = doc.documentElement.clientWidth / 3.75 + 'px'; console.log(100 * doc.documentElement.clientWidht / 3.75) } changeSize(); win.addEventListener('resize', changeSize, false); })(window, document);
Code programming related
Implement publish and subscribe
/* Pubsub */ function Pubsub(){ //Store events and corresponding processing methods this.handles = {}; } Pubsub.prototype = { //Pass in event type and event handling handle on: function (type, handle) { if(!this.handles[type]){ this.handles[type] = []; } this.handles[type].push(handle); }, emit: function () { //Get event type by passing in parameters //Convert arguments to a true array var type = Array.prototype.shift.call(arguments); if(!this.handles[type]){ return false; } for (var i = 0; i < this.handles[type].length; i++) { var handle = this.handles[type][i]; //Execution event handle.apply(this, arguments); } }, off: function (type, handle) { handles = this.handles[type]; if(handles){ if(!handle){ handles.length = 0;//Empty array }else{ for (var i = 0; i < handles.length; i++) { var _handle = handles[i]; if(_handle === handle){ //Remove from array handles.splice(i,1); } } } } }
promise how to realize chain call and return different states
// MyPromise.js // First define three constants to represent the state const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; // newly build MyPromise class class MyPromise { constructor(executor){ // executor It is an actuator, which will be executed immediately after entering // And pass in the resolve and reject methods executor(this.resolve, this.reject) } // Storage state variable, the initial value is pending status = PENDING; // Why do resolve and reject use arrow functions? // If called directly, the normal function this points to window or undefined // Use the arrow function to make this point to the current instance object // Value after success value = null; // Reasons after failure reason = null; // Status after successful change resolve = (value) => { // Status modification can only be performed if the status is wait if (this.status === PENDING) { // Status changed to success this.status = FULFILLED; // Value after successful saving this.value = value; } } // Change status after failure reject = (reason) => { // Status modification can only be performed if the status is wait if (this.status === PENDING) { // Status success to failure this.status = REJECTED; // Reason after saving failure this.reason = reason; } } then(onFulfilled, onRejected) { // Judgment state if (this.status === FULFILLED) { // The callback is called successfully and the value is returned onFulfilled(this.value); } else if (this.status === REJECTED) { // Call the failed callback and return the reason onRejected(this.reason); } } }
Implement Promise.all
// Promise.all function all(promises) { let len = promises.length, res = [] if (len) { return new Promise(function (resolve, reject) { for(let i=0; i < len; i++){ let promise = promises[i]; promise.then(response => { res[i] = response // When the returned result is the last one if (res.length === len) { resolve(res) } }, error => { reject(error) }) } }) }
Object array to tree array
> take entries according to level convert to result data structure const entries = [ { "province": "Zhejiang", "city": "Hangzhou", "name": "West Lake" }, { "province": "Sichuan", "city": "Chengdu", "name": "Jinli" }, { "province": "Sichuan", "city": "Chengdu", "name": "Fang Suo" }, { "province": "Sichuan", "city": "ABA", "name": "jiuzhaigou" } ]; const level = ["province", "city", "name"]; const result = [ { value:'Zhejiang', children:[ { value:'Hangzhou', children:[ { value:'West Lake' } ] } ] }, { value:'Sichuan', children:[ { value:'Chengdu', children:[ { value:'Jinli' }, { value:'Fang Suo' } ] }, { value:'ABA', children:[ { value:'jiuzhaigou' } ] } ] }, ]
Idea: involving tree array, recursive traversal is adopted
function transfrom(list, level) { const res = []; list.forEach(item => { pushItem(res, item, 0); }); function pushItem(arr, obj, i) { const o = { value: obj[level[i]], children: [], }; // Judge whether the value in the passed in array is equal to the item to be passed in const hasItem = arr.find(el => el.value === obj[level[i]]); let nowArr; if(hasItem) { // If yes, the children of the passed in item will be traversed next time nowArr = hasItem.children; }else{ // non-existent Press in arr to traverse the children passed in this item next time arr.push(o); nowArr = o.children; } if(i === level.length - 1) delete o.children; i++; if(i < level.length) { // Recursive traversal pushItem(nowArr, obj, i); } } } transfrom(entries, level);
Native implementation of JS instanceof method
Simple usage
function Fn () {} const fn = new Fn() fn instanceof Fn // true
The implementation is as follows:
// left instanceof right function _instanceof(left, right) { // Constructor prototype const prototype = right.prototype // Real column object property that points to its constructor prototype left = left.__proto__ // Verify prototype chain while (true) { // If it is null, it indicates that the prototype chain has found the top layer, and the true return is false if (left === null) { return false } // Prototype found if (prototype === left){ return true } // Continue looking up left = left.__proto__ } } const str = "abc" _instanceof(str, String) // true
Programming problem
Merge arrays with the same elements
// For example: const arr = [ ['a', 'b', 'c'], ['a', 'd'], ['d', 'e'], ['f', 'g'], ['h', 'g'], ['i'] ] // The returned result after running is: [ ['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h'], ['i'] ] // Idea 1: const arr = [['a', 'b', 'c'], ['a', 'd'], ['d', 'e'], ['f', 'g'], ['h', 'g'], ['i']] function transform(arr){ let res = [] arr = arr.map(el => el.sort()).sort() const item = arr.reduce((pre, cur) => { if (cur.some(el => pre && pre.includes(el))) { pre = pre.concat(cur) } else { res.push(pre) pre = cur } return [...new Set(pre)] }) res.push(item) return res; } transform(arr) // console.log(transform(arr)); // Idea 2: function r (arr) { const map = new Map() arr.forEach((array, index) => { const findAlp = array.find((v) => map.get(v)) if (findAlp) { const set = map.get(findAlp) array.forEach((alp) => { set.add(alp) const findAlp2 = map.get(alp) if (findAlp2 && findAlp2 !== set) { for(const v of findAlp2.values()){ set.add(v) map.set(v, set) } } map.set(alp, set) }) } else { const set = new Set(arr[index]) array.forEach((alp) => map.set(alp, set)) } }) const set = new Set() const ret = [] for (const [key, value] of map.entries()) { if (set.has(value)) continue set.add(value) ret.push([...value]) } return ret }