Please don’t stop to be the person you want to be
Don’t loop through arrays of 1-1000
Array.from({length:1000},(x,y)= >y+1)
Copy the code
CSS Performance Optimization
1.Merge CSS, (because loading3a1KB of CSS is better than loading one100KB CSS is slower)
2.Do not use @import which will affect the current CSS loading speed
3.Avoid CSS hierarchies too deep (best3Level of less than)
4.Remove common styles so that part of the CSS can be cached (this will speed up the first CSS load, depending)
5.Use CSS inheritance care (for example, the parent has color, font, so do not define the child color, font)
6.Use Sprite image cssSprite (combine multiple images into one image so we can reduce image requests)
7.Compress the CSS
Copy the code
Talk about inheritance and the difference between ES5 and ES6 inheritance?
// Es5 inherits the static method of the current method through the prototype chain, and calls the constructor of the parent component with call or apply
/ / es5 inheritance
var fn = function(name){
this.name = name
}
fn.prototype.xname = 'Joe'
var x = function(name){
fn.call(this,name)
}
x.prototype = fn.prototype
x.prototype.constructor = fn
var y = new x('Ming')
y // {name:' xiaoming '} // __proto__ has the current xname attribute as' Zhang Three '.
// ES6 extends the fn component's methods via the extends keyword, using super to call the parent component's constructor
class fn{
constructor(name){
this.name = name
this.xname = 'Joe'
}
}
class x extends fn{
// Super must be added to perform the parent component's constructor so that the child component gets the assignment of the current name
constructor(name){
super(name)
}
}
let y = new x('Joe')
y // {name:' xiaoming ',xname:' Zhangsan '}
Copy the code
Implement fn(1)(2)(3) = 6 and add after it for infinite extension
// It is used now
// 1 return f (Function) so that the method can be used indefinitely
// 2 uses toString and valueOf to call toString and valueOf when no value is retrieved.
// 3 Val is a closure. The current val is always called by f, so it is never collected by garbage collection
let fn = function(x){
let val = x
let f = function(y){
val += y
return f
}
f.toString = function(){
return val + ' '
}
f.valueOf = function(){
return val
}
return f
}
fn(1) (2) (3) / / 6
Copy the code
Vue2. X implementation principle
// Hijacking the current object via defineProperty for bidirectional binding
// defineProperty Cannot hijack an array requires a special pair operation
let ArrayPro = Array.prototype
let ArrayObj = Object.create(ArrayPro);
['pop'.'push'.'splice'.'shift'.'onshift'].forEach(item= >{
ArrayObj[item] = function(){
updataView()
ArrayPro[item].call(this. arguments)
}
})
// Update the view
function updateView(){
console.log('Update view')
}
let reactProperty = function(obj,item,val){
// Recursively listen down. Defineproperty can only listen on one level
observer(val)
Object.defineProperty(obj,item,{
get(){
return val
},
set(newVal){
if(newVal! ==val){
val = newVal
updateView()
}
}
})
}
let observer = function(obj){
// Null equals Typeof Object for historical reasons
if(typeofobj ! = ='object' || obj === null) {
return
}
/ / ArrayObj: 'pop' and 'push', 'splice', 'shift' and 'onshift'
// Objects with these methods call the array's own methods when executed
// The current array case will point to the current ArrayObj so that our array can be listened on
if(Array.isArray(obj)){
obj.__proto__ = ArrayObj
}
for(let item in obj){
// Check that the current data is in obj
if(obj.hasOwnProperty(item)){
reactProperty(obj,item,obj[item])
}
}
}
let objectA = {
a: 1.
v: []
}
observer(objectA)
objectA.a = 2
objectA.v.push(1)
Copy the code
How to deal with the DIFF algorithm in vue.js?
1.Only the same level is compared
2.Replace the current tag (DOM) directly
3.The currentkeyAs with tag, no comparison is made
Copy the code
What is the time complexity of the DIFF algorithm in vue.js? Why is that?
The new vDOM is compared to the old vDOM, so the complexity is O(n2), and then you have to change it (add or delete it), so it's O(n3).
Copy the code
What periodic functions are available in vue.js? When are these periodic functions executed?
1.beforeCreate / / prior to the start
2.Creaed / /
// Determine the current template or render function
3.bedoreMount // Before dom creation
4.Mounted // After dom creation (mount complete)
// beforeUpdate // beforeUpdate
// Updated // DOM rendering is complete
5.beforeDestroy / / before destruction
6.Destroyed / / after destruction
// Parent component nesting lifecycle
1.Father beforeCreate
2.The father Created
3.Father beforeMount
4.The child beforeCreate
5.Son of the Create
6.The child beforeMount
7.The child Mounted
8.Father Mounted
// Parent component destruction
1.Father beforeDestroy
2.The child beforeDestroy
3.The child Destroyed
4.Father is Destroyed
// Parent component updates
1.Father beforeUpate
2.The child beforeUpate
3.The child Upated
4.Father Upated
Copy the code
What is MVC? The MVVM?
// MVC from text we can derive model, view, controller when we click a button
(View) passes the click event, the controller (logic) (Controller) assigns values to a field (model and data (variables)),
When we change the data, we render the DOM of the current view
// MVVM m (model) v (View) VM (VUE control, view module (abstract view))
MVVM is data change view, when our data changes, we modify our view through vUE (VM), and then the view changes through (VM).
To modify our model
Copy the code
Observer versus publish/subscribe?
// A brief introduction of the two modes
Observer mode is for example, you and Xiao Ming both want to drink milk, and then call the milk station. The staff of the milk station will deliver such a pattern to you
This is the observer mode, and the subscription mode is that you call the milk station agent, not directly contact with the milk station, the milk station only need to deliver goods to the agent
Yes, and all you have to do is contact the agent, and then the milk station will be connected instead of having to deal with delivery and all that kind of stuff by subscription publishing.
// Observer mode
/ / xiao Ming
let subject = function(name){
this.name = name
}
subject.prototype.go = function(){
console.log(`The ${this.name}Sour sweet really good to drink ')
}
/ / service station
let observer = function(name){
this.name = name
this.list = []
}
observer.prototype.push = function(obj){
this.list.push(obj)
}
observer.prototype.go = function(){
this.list.forEach(item= >{
item.go()
})
}
let server = new observer('Milk Station')
// Xiaoming subscribs milk
server.push(new subject('Ming'))
// Xiao Hong subscribs milk
server.push(new subject('little red'))
// The milk station distributes milk
server.go()
// I will write the following comments here for the ES6 version, but almost
// Publish a subscription
/ / agent
let subject = function(name){
this.name = name
}
subject.prototype.go = function(min){
console.log(`${min}Sour sweet really good to drink ')
}
let pubSub = function(){
this.fnList = {}
}
pubSub.prototype.push = function(type, fn){
this.fnList[type] = fn
}
pubSub.prototype.go = function(type){
let fn = this.fnList[type]
fn.call(this. arguments)
}
let pub = new pubSub()
let min = new subject('Ming')
pub.push('min',min.go)
pub.go('min')
Copy the code
The difference between an arrow function and a normal function
1The arrow function this points to this that does not always point to the context because of the call, apply, bind impression. Ordinary functions point to the caller
2Arrow functions have no arguments with (... Rest) = >{}Instead, arrow functions are anonymous
3Arrow functions have no prototypeconstructor
Copy the code
Detailed process from entering url to page presentation
1. Enter the url
2.dnsparsing
3. Establishtcplink
4. The client sends a request
5. The server processes the request
6. The server returns data
7. The client receives data
8. Client displayhtml
9. The client sends a requesthtmlResources needed inside (img.js.css)
10. (domTrees andstyleRules)renderThe tree is then rendered
Copy the code
HTTPS implementation principles (the more detailed, the better)
1. The client sends a request to the server (port 443) (HTTP port 80).
2. The server returns the current digital certificate and public key
3. The client verifies the digital certificate, generates a random number, generates a symmetric encryption key with the public key, and sends the key to the server
4. The server parses the secret key to obtain a random number, encrypts the data to be transmitted through symmetric encryption, and sends it to the client
5. The client parses the encrypted data to obtain the data
Copy the code
Page rendering process
1.Generate a dom tree
2.Generate CSS Rules
3.Loading js will affect our generation 👆 (it will clog the page so try to put it last)
3.Generate our render tree
4.Render our page
5.Redraw and backflow (backflow costs more than painting)
// Redraw: the page structure is unchanged, such as color, font size
// backflow: dom structure changes must trigger redrawing, such as display: node, which changes the page structure
Copy the code
How to optimize performance (the problem is big and we stratify)
Write the code
We use closures as little as possible
Avoid the use ofwithstatements
Code loop optimization
Use innerHTML for faster performance
Merging DOM operations
modular
When loading
Combination of CSS
Use Sprite (load10zhang1K pictures are better than loading1zhang100K is slower.)
Use CNDS
Lazy loading
Use the cache
Using lazy loading
Put back the script
The overall idea is to reduce the number of requests, reduce CPU usage, and use more local caching
Copy the code
Understanding of front-end modularity
Module is mainly divide and conquer, reuse and decouple, which is beneficial to our development.
There are two principles for how to extract our modules
1: The first one is reuse, reducing unnecessary duplication of code.
2: is a relatively independent module. How to understand? This means that if you write a music player component, you can use it in one place, but this one is relatively independent
Functional independence and no adhesion to other components,
When using components, we should define more default parameters (see business).
Copy the code
What would you say if you were given a project to start from scratch
1. Review the requirements first to see whether there are any loopholes in the requirements and whether they are reasonable
2. Requirements breakdown (assessment time) (some will look at test cases first)
3. Write documents for front-end negotiation (if you have time, try to draw a UML class diagram)
4. Allocate demand (get started)
5. Complete (self-test, unit test)
6. Test measurement
7. Project launch
8. Walk online
Copy the code
The difference between defer and async properties in the Script tag
1.asyncThat's asynchronous loading
2.deferSo load it first and don't execute it, wait until all the elements are parsed,DOMContentLoadedBefore the event triggers execution
Copy the code
Write a bind
First let's consider that bind returns afunctionthenthisPoint to incomingobj
First of all, let's pick oneobj
let obj = {
name : 'Joe'
}
Function.prototype.myBind = function(){
// Get all the values we passed
let arr = [...arguments]
// Get the first object
let obj = arr.shift()
// Go to the current method
let _this = this
// bind is a method for return
return function(){
// This refers to the obj we passed in, followed by some of our arguments
_this.apply(obj,[...arr,...arguments])
}
}
/ / use
function name(name){
console.log(name)
this.name = name
}
name.myBind(obj,obj.name)()
Copy the code
Write a call
First let's consider that some calls pass in a bunch of values (obj,x,x,x,x,x,x,x,x,x,x,x) and are executed directly
let obj = {
name: 'Joe'
}
Function.prototype.myCall = function(){
let arr = [...arguments]
// If there is no current input, then it is window
let obj = arr.shift() || window
// Assign to fn so that we can assign our this pointer
obj.fn = this
/ / execution
obj.fn(... arr)
delete obj.fn
}
/ / execution
function name(name){
console.log(this)
console.log([...arguments])
this.name = name
}
name.myCall(obj,obj.name,1.2.3.4.5)
Copy the code
Handwritten apply
The difference between apply and call is that the values passed in are arrays
let obj = {
name: 'Joe'
}
Function.prototype.myApply = function(){
let arr = [...arguments]
let obj = arr.shift() || window
obj.fn = this
obj.fn([...arr])
delete obj.fn
}
/ / execution
function name(name){
console.log(this)
console.log(name)
}
name.myApply(obj,obj.name,1.2.3.4.5)
Copy the code
Handwritten map and Filter
function map(arr,fun) {
let ar = []
for(let i=0; i<arr.length; i++){
ar.push(fun(arr[i],i,arr))
}
return ar
}
map([1.2.3.4.5],(item,index)=>{return item+index})
/ /,3,5,7,9 [1]
function filter(arr,fun) {
let ar = []
for(let i=0; i<arr.length; i++){
if(fun(arr[i],i,arr)) {
ar.push(arr[i])
}
}
return ar
}
filter([1.2.3.4.5],(item)=>item>2)
/ / / three, four, five
Copy the code
Handwritten ajax
let ajax = new XMLHttpRequest()
ajax.open('get'.'www.xxx.xx/xxx'.false)
ajax.onreadystatechange = function(){
if (ajax.readystate == 4) {
// The response content is parsed and can be invoked on the client
if (ajax.status == 200) {
// The client request succeeded
alert(ajax.responseText);
}
}
}
ajax.send()
Copy the code
Promise limits the number of concurrent requests
// Promise limits the number of concurrent requests, such as a maximum of 10 interfaces requested by the applets, then the eleventh request must wait until the tenth one is finished before the request can be made, and we pass
// Promise to implement
class limitPromise{
constructor(max){
// Maximum number of requests
this._max = max
// The current number of requests
this._count = 0
// Request tasks currently exceeded
this._tasklist= []
}
// fn The current request function args the current request parameters
call(fn,... args){
return new Promise((resolve,reject) = >{
let task = this._createTask(fn,args,resolve,reject)
if(this._count>=this._max){
this._tasklist.push(task)
}else{
task()
}
})
}
// Create a task
_createTask(fn,args,resolve,reject){
return (a)= >{
fn(... args)
.then(resolve)
.catch(reject)
.finally(_= >{
this._count--
if(this._tasklist.length){
let task = this._tasklist.shift()
task()
}
})
this._count++
}
}
}
let limit = new limitPromise(2)
// I am a request
let fn = function(){
xxxx
}
let ajax = (data) = >{
limit._call(fn,data)
}
Copy the code
Shallow copy
Shallow copy is to copy only the first layer of data
let obj = {
a: 1.
b: 2.
arr: [1, {a: 1},1[1]]]
}
/ / 1
let obj = Object.assign({},obj)
/ / 2
let fn = (obj) = >{
let ob = {}
for(let item in obj){
if(obj.hasOwnProperty(item)){
ob[item] = obj[item]
}
}
return ob
}
fn(obj)
Copy the code
Deep copy
Deep copy is a copy of all current layers
let obj = {
a: 1,
b: 2,
arr: [1,{a: 1},[1,[1]]]
}
// Convert string and then convert JSON
// This is problematic, and our funciton Symbol and others do not support it
let obj1 = JSON.pase(JSON.stringify(obj))
// So we can only recurse (object, array)
let obj = {
a: 1,
b: 2,
arr: [1,{a: 1},[1,[1]]]
}
let clone = (obj)=>{
let val
let type = Object.prototype.toString.call(obj)
if(type= = ='[object Object]') {
val = {}
}else if(type= = ='[object Array]') {
val = []
}else{
return obj
}
for(let item in obj){
let value = obj[item]
let type = Object.prototype.toString.call(obj)
if(type= = ='[object Object]'||type= = ='[object Array]') {
val[item] = clone(value)
}else{
val[item] = value
}
}
return val
}
clone(obj)
Copy the code
Write a pomise
function myPromise(fn){
this.state = 'pending'
this.value = ' '
this.error = ' '
this.onResolveFn = []
this.onResjectFun = []
let resolve = (value) = >{
if(this.state==='pending') {
this.state = 'resolved'
this.value = value
this.onResolveFn.forEach(fn= >fn(value))
}
}
let resject = (error) = >{
if(this.state==='pending') {
this.state = 'resjected'
this.error = error
this.onResjectFun.forEach(fn= >fn(error))
}
}
fn(resolve,resject)
}
myPromise.prototype.then = function(resolveFn,resjectFun){
/ / asynchronous
if(this.state==='pending') {
if(typeof resolveFn ==='function') {
this.onResolveFn.push(resolveFn)
}
if(typeof resjectFun ==='function') {
this.onResjectFun.push(resjectFun)
}
}
/ / synchronize
if(this.state==='resolved') {
if(typeof resolveFn ==='function') {
resolveFn(this.value)
}
}
if(this.state==='resjected') {
if(typeof resjectFun ==='function') {
resjectFun(this.error)
}
}
}
let promise1 = new myPromise((resolve,resject) = >{
resolve(1)
}).then(res= >{
console.log(res)
})
let promise2 = new myPromise((resolve,resject) = >{
setTimeout(function(){
resolve(2)
},2000)
})
promise2.then(res= >{
console.log(res)
})
Copy the code
Image stabilization
Anti-shake means that you can do it once in a certain amount of time, and there are two versions where you do it first, and then how long it takes to click again. The other is delayed execution
let dob = function(){
let arr = [...arguments]
let fn = arr.shift()
let time = arr.shift()||1000
let timeout = null
// Delay execution
return function(){
let that = this
if(timeout){
clearTimeout(timeout)
}
timeout = setTimeout(function(){
// The execution can be delayed until the timer ends
fn.apply(that,[...arr])
},time)
}
// Execute immediately
return function(){
if(timeout){
clearTimeout(timeout)
}
// Show is true only when null is present
letshow = ! timeout
timeout = setTimeout(function(){
timeout = null
},time)
// There is no need to put the current execution method in the timer
// So show is true at the beginning, so execute immediately, false at the second click, and only when time has passed
if(show){
fn.apply(this,[...arr])
}
}
}
Copy the code
The throttle
Throttling is performed only once in a certain period of time and does not overwrite previous ones. There are two kinds, one is to use time, the other is to use timer
let thr = function(){
let arr = [...arguments]
let fn = arr.shift()
let time = arr.shift()||1000
/ / time
let oldDate = 0
return function(){
let newDate = Date.now()
if(newDate>oldDate+time){
oldDate = newDate
fn.apply(this,[...arguments,...arr])
}
}
/ / timer
let show = true
return function(){
let context = this
let arg = [...arguments]
if(show){
show = false
setTimeout(function(){
show = true
fn.apply(context,[...arg,...arr])
},time)
}
}
}
Copy the code
V – model principle
The V-Model principle is that VUE helped us build in a short version of $EMIT
/ / the parent component
<xxx v-model='message'></xxx>
// js
export default{
.
data(){
return{
message: 1
}
}
}
/ / child component
<template>
<div @click='$emit('input',value+1)'>
{{value}}
</div>
</template>
<script>
export default{
props:['value']
}
</script>
// Vue has built in @input and value equal to the value of model
// The default is
export default{
model: {
prop: 'value'.
event: 'input'
},
props:['value']
}
Or let's change the values on this side
<template>
<div @click="$emit('click',value1+1)">
{{value1}}
</div>
</template>
<script>
export default{
model: {
// Define the current value
prop: 'value1'.
// Defines the event for the current return
event: 'click'
},
props:['value1']
}
</script>
// I suggest you try it. Self-feeding
Copy the code
Implicit conversion
/ / add
1+'1' / / 11
1+'true' // 1true
1+true // 2 1+Number(true)
1+undefinede // NaN equals 1+Number(undefinede)
1+null // 1 1+Number(null)
/ / contrast
"2">10 // false Number(2)>10
"2">"10" // true converts to character comparison
"abc">"b" // false is converted to characters for comparison
! [] = =0 // true ! [] returns false. False compares to 0, so it is true
[] = =0 // true [] calls valueOf and toString to get an empty string and then compares both with 0 to false so it is true
[] = =! []// true one is false and the other is an empty string so it is true
[] = = []// false Two reference types are compared to the stack, so false
{} = =! {}// false {} valueOf and toString get [object object]! {} is false so the two are inconsistent
= = {} {}// Two reference type comparisons compare the current stack
var a = ?
if(a==1&&a==2&&a==3) {
console.log(What is a equal to?)
}
a = {
value: 0.
toString: function(){
return ++a.value
}
}
// Objec calls valueOf or toString methods before comparison
Copy the code
Rebuild teacher chenhongdong’s MVVM
1.Example Add listening to an array
2.Observe Monitors data
3.Publish subscription model Dep Watch
4.The form of a computed
5.compile
6.mounted
let ArrayProtoType = Array.prototype;
let arrayProtoTypeObject = Object.create(ArrayProtoType);
['pop'.'push'.'onshift'.'shift'.'splice'].forEach(item= >{
// Add an array to obj
arrayProtoTypeObject[item] = function() {
ArrayProtoType[item].call(this. arguments)
}
})
const reactProperty = function(obj,item,value) {
let dep = new Dep()
// Listen recursively
observer(value)
Object.defineProperty(obj,item,{
get(){
Dep.target && dep.addSub(Dep.target)
return value
},
set(newVal){
// You can change the value only when the value is different
if(newVal! ==value){
value = newVal
// We add the listener again when the value is changed
observer(value)
dep.notity()
}
}
})
}
// Publish a subscription
const Dep = function () {
this.subs = []
}
Dep.prototype = {
addSub(sub){
this.subs.push(sub)
},
notity(){
this.subs.forEach((sub) = >sub.update())
}
}
const Watch = function(vm,reg,fn) {
this.vm = vm
this.fn = fn
this.reg = reg
Dep.target = this
this.reg.split('. ').reduce(function(x,y){
return x[y]
},this.vm)
Dep.target = null
}
Watch.prototype.update = function() {
let val = this.reg.split('. ').reduce(function(x,y){
return x[y]
},this.vm)
this.fn(val)
}
// Listen for data
const observer = function(obj) {
if(typeofobj! = ='object'||obj === null) {
return
}
if(Array.isArray(obj)){
// Switch the pointer
obj.__proto__ = arrayProtoTypeObject
}
for(let item in obj){
reactProperty(obj,item,obj[item])
}
}
let Mvvm = function(option = {}) {
let data
this.$option = option
this.$el = option.el
data = this._data = option.data
// Data listener
observer(data)
$option.data. X = app.$option.data
for(let item in data){
Object.defineProperty(this,item,{
// It can be deleted
configurable: true.
get(){
return data[item]
},
set(val){
data[item] = val
}
})
}
initComputed.call(this)
// Data rendering
compile(this.$el,this)
this.$option.mounted.call(this)
}
// Render the template
const compile = function(el,vm) {
// Get the current total DOM
vm.$el = document.querySelector(el)
// Create a memory container
let fragment = document.createDocumentFragment()
while(child = vm.$el.firstChild){
// operate on the current DOM memory
fragment.appendChild(child)
}
function replace(fragment){
// Replace the DOM under the current memory container
let reg = / \ {\ {(. *?) \}\}/g
Array.from(fragment.childNodes).forEach(node= >{
// The current is V-model
// on the dom attribute
if(node.nodeType===1) {
// Get the property on the current DOM
let nodeAttr = node.attributes
Array.from(nodeAttr).forEach(attr= >{
// The current attribute name is V-model
let name = attr.name
// The value of the current property is message
let value = attr.value
if(name.indexOf('v-') >- 1) {
// There is currently a v- assignment on the value property
// Assign a value to the current Node VM [value] and listen on the MVVM
node.value = vm[value]
}
// Listen on attributes
new Watch(vm,value,(newVal)=>{
node.value = newVal
})
// The default value of the v-model method to add input comes from that
node.addEventListener('input'.function(event){
let newVal = event.target.value
/ / triggers the set
vm[value] = newVal
})
})
}
// dom text
{{}}}
if(node.nodeType===3) {
let text = node.textContent
text.replace(reg,(x,y)=>{
// Assign to the case of A.X.X
let val = y.split('. ').reduce(function(x,y){
return x[y]
},vm)
// Listen on attributes
new Watch(vm,y,(newVal)=>{
node.textContent = newVal
})
node.textContent = val
})
}
// Recursive calls to children of children may have many levels
if(node&&node.childNodes){
replace(node)
}
})
}
replace(fragment)
vm.$el.appendChild(fragment)
}
const initComputed = function() {
let vm = this
let computed = this.$option.computed
Object.keys(computed).forEach(item= >{
Object.defineProperty(vm,item,{
get: typeof computed[item] === 'function'? computed[item]: computed[item].get,
set: (a)= >{}
})
})
}
/ / define MVVM
let app = new Mvvm({
el : '#app'.
computed: {
xx(){
return this.message
}
},
data: {
a : 1.
message: 'hello world'
},
mounted(){
}
})
setTimeout(function(){
app.message = 'jinjinjin'
},2000)
Copy the code
The last
See the end 🙏 thank you, more like on github facing ❤️ is the best for me to encourage, I will try to share some of my own experience and the correct way to eat
Seek to rely on the spectrum push (Beijing area) can leave a message I +. =