Performance optimization

Performance optimization is always the focus of the interview, and performance optimization is even more important for React

  • Used in the pagesetTimout(),addEventListener()And so on, in timecomponentWillUnmount()The destruction of
  • Using asynchronous components
  • useReact-loadableDynamically loading components
  • shouldComponentUpdate(SCU),React.PureComponent,React.memo
  • ImmutableJS with immutable values
shouldComponentUpdate (nextProps, nextState) {
    return true// Can render, execute render(), default returntrue
    return false// Do not render, render()}Copy the code

When should I use shouldComponentUpdate

In React, by default, all child components are unconditionally updated!!!!!! if the parent component’s data is updated ShouldComponentUpdate () shouldComponentUpdate() should not be used every time, but should only be optimized when needed

class App extends React.Component {
    constructor () {
        this.state = { list: [] }
    }
    render () {
        returnRender () */} <Header /> < list data={this.state.list} </div>)}}Copy the code

ShouldComponentUpdate () : why should React setState() be immutable

// In the parent componentchangeList() {this.state.list.push({id: 2}) this.setState({list: this.state.list})} // Import _ from child components'lodash'ShouldComponentUpdate (nextProps, nextState) {// Array_props ();if (_.isEqual(nextProps.list, this.props.list)) {
        return false// equal, not render}return true// not equal, render}Copy the code

The subcomponent will never render because in shouldComponentUpdate() this.state.list.push() has modified this.props. List, This.setstate () modifies the nextProps. List so the depth comparison between the two values will always be the same.

PureComponent and memo

  • Class componentPureComponent, stateless components (stateless) usedmemo
  • PureComponent, shallow comparisons implemented in the SCU
  • Shallow comparisons have been used in most cases (try not to do deep comparisons)

PureComponent differs from regular Components in that it comes with a shouldComponentUpdate() and shallow comparison

The usage / / memofunctionMyComponent (props) {/* Use props to render */} // areEqual also does not passfunction areEqual(prevProps, nextProps) {
    if (prevProps.seconds===nextProps.seconds) {
        return true
    } else {
        return false}}export default React.memo(MyComponent, areEqual)
Copy the code

immutable.js

  • Embrace immutable values
  • Basic shared data (not deep copy), fast
  • There are learning and migration costs

Common basic interview questions

How does the React component communicate

  1. Parent components communicate via properties and props
  2. Communicate through context
  3. Communicate via Redux

Enclosing setState ()

import React from 'react'

class App extends React.Component {
    constructor (props) {
        super(props)
        this.state = { count: 0 }
    }
    componentDidMount () {
        this.setState({ count: this.state.count + 1 })
        console.log(this.state.count) // 0
        this.setState({ count: this.state.count + 1 })
        console.log(this.state.count) // 0
        setTimeout(() => {
            this.setState({count: this.state.count + 1 })
            console.log(this.state.count) // 2
        }, 0)
        setTimeout(() => {
            this.setState({count: this.state.count + 1 })
            console.log(this.state.count) // 3
        }, 0)
        // setTimeout(function() {// this.setState({count: this.state.count + 1}) // console.log(this.state.count) // error, this indicates a problem //}, 0)}render () {
        return <h1>{this.state.count}</h1>
    }
}

exportDefault App // Returns higher-order functionsCopy the code

What is the nature of JSX…..

Front-end rich text dangerouslySetInnerHTML

const rawHtml = '<div><p>Title</p></div>'Const rawHtmlData = {__html: rawHtml // there is an underline here}return <div dangerouslySetInnerHTML={rawHtmlData}></div>
Copy the code

Two kinds of binding events

<button onClcik={bindClcik1.bind(this)}> 使用 .bind(this) </button>
<button onClcik={bindClcik2}> arrow function </button> // use class built-in function, need to redirect thisbindClcik1 () { alert('bindClcik1'} // To use static methods, do not use arrow functionsbind(this)
bindClick2 = () => { alert('bindClcik2')}Copy the code

Event, default Event, Event bubbling

The Event object printed here is the SyntheticEvent wrapped by React (see __proto__. Constructor). React standardizes event objects so that they have the same properties across browsers.

The React event binding is completely different from the Vue event binding. The Vue event binding is the same element as the Vue event binding. The React event binding is the document object and the binding element is the current element. All React events are going to be mounted on document unlike DOM events.

Vue events are native, and events are mounted to the current element just like DOM events

<a href="www.baidu.com" onClick={this.getEvent} target="blank">Get Event</a> getEvent = (Event) => {event.preventdefault () // preventDefault event.stoppropagation () // prevent bubblings Console. log(event) // non-native event console.log(event.nativeevent) // get nativeEvent console.log(event.nativeevent.target) // Bind the event object, here is the < a > < / a > the console. The log (event. NativeEvent. CurrentTarget) / / trigger event object, here is the document}Copy the code

Event pass arguments

Pass the parameter through.bind()

<div onClick={this.getParams1.bind(this, 'id1'.'title1')}>get params 1</div>

getParams1 (id, title, event) {
    console.log('id', id)
    console.log('title', title)
    console.log('event'// The last parameter is the event object}Copy the code

Pass the parameter through the arrow function

<div onClick={(event) => { this.getParams2('id2'.'title2', event) }}>get params 2</div>

getParams2 (id, title, event) {
    console.log('id', id)
    console.log('title', title)
    console.log('event', event) 
}
Copy the code

The form

<div>
    <label htmlFor="userName"> < / label > < input value = {this. State. The userName} onChange = {this. HandleInputChange. Bind (this)} / > < / div > / / similar two-way data binding HandleInputChange (even t) {const userName = event.target.value this.setState(() => ({userName})) Event this.setState(() => ({userName = event.target.value}))}Copy the code

Component and the cords

Ordinary arguments/functions

Child text / / parent component < div > < = {this. State. The text} / > < / div > / / subcomponents < div > < p > {this. Props. Text} < / p > < / div >Copy the code

Attribute type checking

import PropTypes from 'prop-types'/ / for checking TodoItem. The parameters passed strong propTypes = {content: propTypes. String. IsRequired, / / limit for the string and will pass}Copy the code

setState()

  1. Immutable values
  2. It may be an asynchronous update
  3. It may be merged
This. setState({count: This.state. count + 1}) const count = this.state.count + 1 this.setState({count})Copy the code

Modify array values correctly

// shouldCompententUpdate shouldsetState (() => ({list1: This.state.list1. concat(100), // Append to list2: [...this.state.list2, 100], // Append to list3: This.state.list3. slice(0, 3) // Slice list4: this.state.list4.filter(item => item > 100) // filter})Copy the code

Modify the object value correctly

this.setState(() => ({ obj1: Object.assign({}, this.state.obj1, {a: 100}), obj2: {... this.state.obj2, a: 100} }))Copy the code

Typically, setState() updates data asynchronously

Const count = this.state.count + 1 this.setState({count: count}, () => {// This function has no default arguments // like Vue$nextTickConsole. log(this.state.count) // Prints the updated value}) console.log(this.state.count) // Prints the updated valueCopy the code

SetState () updates data synchronously. In setTimeout(), setState() is synchronized

setTimeout(() => {
    const count = this.state.count + 1
    this.setState({ count })
    console.log(this.state.count)
})
Copy the code

For self-defined DOM events, setState() is synchronized

componentDidMount () {
    document.body.addEventListener('click', () => {
        const count = this.state.count + 1
        this.setState({ count })
        console.log(this.state.count)
    })
}
Copy the code

The result is executed only once, similar to object.assgin ().

This.state. count = 0 this.setState({count: this.state.count + 1}) this.setState({count: this.state.count + 1}) This.state. count + 1}) this.setState({count: this.state.count + 1}) this.state.count = 1Copy the code

[key] Functions passed in cannot be merged because functions cannot be merged

SetState ((prevState, props) => {this.state.count = 0 this.setState((prevState, props) => {return {
       count: prevState.count + 1
   } 
})
this.setState((prevState, props) => {
   return {
       count: prevState.count + 1
   } 
})
this.setState((prevState, props) => {
   return{count: prevstate. count + 1}}) this.state.count = 3Copy the code

Component life cycle

Initialization initialize

  • constructor() : classThe React constructor is not unique to React

Mounting a mount

  • componentWillMount(): automatically executed when the component is about to be mounted to the page;
  • render(): page mount;
  • componentDidMount(): automatically executes after the component is mounted to the page;

ComponentWillMount () and componentDidMount() are only executed when the page is first mounted, and are not re-executed when state changes

Updation component updated

  • shouldComponentUpdate(): The lifecycle requires that one be returnedboolType of result if returnedtrueComponent updates normally, if returnedfalseComponents will not be updated;
  • componentWillUpdate(): Component is executed before being updated, ifshouldComponentUpdate()returnfalse, will not be executed;
  • componentDidUpdate(): Execute after component update is completed;

ComponentWillReceiveProps () : props unique lifecycle, execute the following conditions:

  1. The component receives parameters from the parent component;
  2. Only the parent componentrender()If executed, the life cycle of the child component is executed;
  3. If the component first exists in the parent component, it is not executed;
  4. Execute if the component already exists in the parent component;

Unmounting The component is uninstalled

  • componentWillUnmount()Executes when a component is about to be removed from the page.

Life cycle simple use scenario

  1. useshouldComponentUpdate()Prevent pages from rendering unnecessarily
# Performance optimization with lifecycle
shouldComponentUpdate () {
    if(nextProps.content ! == this.props.content) {return true;
    }
    return false;
}
Copy the code
  1. Ajax requests initial page datacomponentDidMount()

You can’t write it in Render () because it’s called repeatedly, or in componentWillMount(), which conflicts with RN and other frameworks, or you can write it in here, again only once.

It is also possible, but not recommended, to write in the constructor() function.

import axios from 'axios'

componentDidMount () {
    axios.get('/api/todolist').then((res) => {
      console.log(res.data);
      this.setState(() => ({
        list: [...res.data]
      }));
    }).catch((err) => {
      console.log(err);
    });
}
Copy the code

Stateless components (function components)

We can define a component as stateless when it has only one render() function, and stateless components have only one function. A stateless component performs better because it is just a function, whereas a normal component is a class.

  • Pure functions
  • Input props, output JSX
  • No instance
  • No life cycle
  • There is no state
  • You cannot extend other methods
function List (props) {
    const { text } = this.props
    return (
        <div>{text}</div>
    )
}
Copy the code

Uncontrolled component

class App extends React.Component {
    constructor (props) {
        super(props)
        this.state = {
            name: ' ',
            flag: true} this.nameinputref = react.createref () // createRef this.fileinputref = react.createref () // createRef this.nameinputref = react.createref () // createRef}render () {
        return<div> {/* defaultValue is used instead of value, Use ref */} <input defaultValue={this.state.name} ref={this.nameInputRef} /> <button OnClick ={this.alertname.bind (this)}>alert value</button> {/* file must use dom to obtain data */} <inputtype="file" ref={this.fileInputRef} />
            </div>
        )
    }
    alertName() {const ele = this. NameInputRef. Current / / by ref for dom node alert (ele. Value)}}Copy the code

Portals portal

Use Portals to render on the body, with fixed elements placed on the body for better browser compatibility.

Common usage scenarios:

  1. The parent component overflow: Hidden, but the child component wants to show;
  2. The z-index of the parent component is too small;
  3. Fixed needs to be placed in the first layer of the body;
import ReactDOM from 'react-dom'
render () {
    return ReactDOM.creatPortal(
        <div>{this.props.children}</div>,
        document.body
    )
}
Copy the code

The context context

Usage scenario: Common information (language, theme) is passed to each component, and if there is too much hierarchy in the component, it can be cumbersome to pass it in props and overkill it in redux.

import React from 'react'// Create a Context and fill in the default value (any js variable)export const {Provider,Consumer} = React.createContext("Default name"Constructor (props) {super(props) this.state = {theme:'light'}}render() {this.state.theme is used here so that it can be modified. The initial value is the default value, and the shared data in // value cannot be modifiedreturn( <Provider value={this.state.theme}> .... <button onClick={this.changeTheme}></button> </Provider>)} import {Consumer} from is called in the child component"./index"; // Import the Consumer container for the parent componentrender () {
    returnThe Consumer container can take the theme property passed above and display the corresponding <Consumer> {theme => <div> child component. Get the parent component's value: {theme} </div>} </Consumer>)}Copy the code

Asynchronous components

Const LazyComponent = react.lazy (() => import())'./lazyDemo'In Suspense </div> <LazyComponent /> </React.Suspense> </React.Copy the code

The withdrawal of the component’s common logic

  • React deprecated mixins in Vue
  • High-level component HOC
  • Render Props

High order component

Higher-order components are not a feature, but a pattern

Const HOCFactory = (Component) => {class HOC extends React.Component {// Define the common logic for multiple components hererender () {
            return<Component {... Thi. Props} /> //return HOC
}
const MyComponent1 = HOCFactory(WrappedComponent1)
const MyComponent2 = HOCFactory(WrappedComponent2)
Copy the code

The actual case

import React from 'react'Const withMouse = (Component) => {class withMouseComponent extends React.Component {constructor(props) {const withMouse = (Component) => {class withMouseComponent extends React.Component {constructor(props) { super(props) this.state = { x: 0, y: 0 } } handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }) }render() {
            return (
                <div style={{ height: '500px'}} onMouseMove={this.handleMouseMove}> {/* 1. 2. Add mouse properties */} <Component {... this.props} mouse={this.state}/> </div> ) } }returnWithMouseComponent} const App = (props) => {const a = props. A const {x, y} = propsreturn (
        <div style={{ height: '500px' }}>
            <h1>The mouse position is ({x}, {y})</h1>
            <p>{a}</p>
        </div>
    )
}
exportDefault withMouse(App) // Returns higher-order functionsCopy the code

Render Props

Key idea: Pass the state of the class component as Props to the pure function component through a function

class Factory extends React.Component {
    constructor() {this.state = {/* where state is the common logical data of multiple components */}} /* Modify state */render () {
        return<div>{this.props. Render (this.state)}</div>}} const App = () => {/* Render is a function */ <Factory render={(props) => <p>{props.a} {props.b}... </p> } /> }Copy the code

Redux single data stream

  1. dispatch(action)
  2. Reducer to produce newState because
  3. Subscribe trigger notification

Redux single data flow diagram

React-router

Routing patterns

  • Hash mode (default), for example, baidu.com/#/user/10
  • H5 History mode, for example, baidu.com/user/20

The latter requires server support, so there is no special requirement to choose the former

Common components

import {
    HashRouter,
    BrowserRouter,
    Switch,
    Route
} from 'react-router-dom'

function RouterComponent () {
    return (
        <BrowserRouter>
            <Switch>
                <Route path='/'Exact Component ={Home}> {/* Dynamic routes */} <Route path='/detail/:id'Exact component={Detail}></Route> {/* Match 404 pages */} <Route path=The '*' exact component={NotFound}></Route>
            </Switch>
        </BrowserRouter>
    )
}
Copy the code

Routing hop

  • Label jump, pass<Link to="/">This implicit A tag jump
  • JS jump,import { useHistory } from 'react-router-dom' && history.push('/')

Route configuration lazy loading

import React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'

const Home = React.lazy(() => import('./pages/Home'))
const Detail = React.lazy(() => import('./pages/Detail')) const App = () => ( <BrowserRouter> <React.Suspense fallback={<div>Loading... </div>}> <Switch> <Route exact path="/" component={Home} />
                <Route exact path="/detail" component={Detail} />
            </Switch>
        </React.Suspense>
    </BrowserRouter>
)
Copy the code

Vue principle

Data Driven View (MVVM, setState), Vue MVVM (Model + View + ViewModel)

Vue responsive

Once the data of the component data changes, it immediately triggers the update of the view, realizing the first step of the data-driven view

Core API: Object.defineProperty, Object.defineProperty has some disadvantages, Vue3.0 starts to enable Proxy, Proxy has compatibility issues and cannot polyfill (compatibility problem solution)

// object.defineProperty base use const data = {} const name ='Actoress'
Object.defineProperty(data, "name", {
    get: function () {
       console.log('get')
       return name
    },
    set: function (newValue) {
        console.log('set') name = newValue}}) // Call console.log(data.name) // get() execute =>'Actoress'
data.name = 'Wu' // set()Copy the code

The depth of the listening

  • Deep monitoring, need to recurse to the end, one-time calculation is large
  • Unable to listen for new/deleted properties
  • The array needs to be redefined as an array prototype
// Trigger to update the viewfunction updateView() {
   console.log('View Update'Const oldArrayProperty = array. prototype; // Create a new object with the prototype pointing to oldArrayProperty, Const arrProto = object.create (oldArrayProperty); ['push'.'pop'.'shift'.'unshift'.'splice'].forEach(methodName => {
   arrProto[methodName] = function() {updateView() // Trigger view update oldArrayProperty[methodName]. Call (this,... arguments) // Array.prototype.push.call(this, ... Arguments)}}) // Redefine attributes to listen tofunctionDefineReactive (target, key, value) {// Deep listening observer(value) // Core API Object.defineProperty(target, key, {get() {
           return value
       },
       set(newValue) {
           if(newValue ! == value) {// deep listen observer(newValue) // set newValue // Value = newValue // triggers the updateView updateView()}}})} // listens for object propertiesfunction observer(target) {
   if(typeof target ! = ='object'| | target = = = null) {/ / not object or arrayreturn// array.prototype.push = // array.prototype.push =function () {
   //     updateView()
   //     ...
   // }

   if(array.isarray (target)) {target.__proto__ = arrProto}for inYou can also iterate over groups of numbers.for (let key inTarget) {defineReactive(target, key, target[key])}} const data = {name:'Actoress',
   age: 20,
   info: {
       address: 'Beijing'}, nums: [10, 20, 30]} // Monitor data observer(data) // test // data.name ='Wu'
// data.age = 21
// // console.log('age', data.age)
// data.x = '100'Vue. Set // delete data.name // delete attribute, Vue. Delete // data.info.address ='Shanghai'// Deep monitorCopy the code

Virtual DOM (Virtual DOM)

Vdom is the building block for implementing Vue and React

  • It’s hard to reduce the number of computations because of the complexity
  • Can we move more computing to JS computing? Because JS is fast
  • Vdom uses JS to simulate the DOM structure, calculate the smallest changes, and manipulate the DOM

Simulate the DOM structure with JS

Use snabbDOM to manipulate the virtual DOM

Documents: github.com/snabbdom/sn… Main API H () && vNode && Patch ()

The Diff algorithm

  • Diff algorithm is the most core and critical part of VDOM
  • The diff algorithm can be seen in everyday use of Vue React (loop key)

Time complexity of optimizing pre-tree Diff (n^3)

  1. Traverse Tree1, traverse Tree2
  2. The sorting
  3. Let’s say I have 1000 nodes, and I have to compute 100 million times, and the algorithm doesn’t work

Time complexity after optimization (n^1)

  1. Compare only the same level, not across levels
  2. If the tag is different, delete it and rebuild it
  3. If the tag and key are the same, they are considered the same node and are not compared in depth

The React principle

Data-driven view (MVVM, setState)

  • Data-driven view – Reactthis.setState()
  • Functional programming: Functional programming is a programming paradigm in which the two most important concepts are pure functions and immutable values

JSX nature

  • JSX is equivalent to Vue templates
  • Vue templates are not HTML
  • JSX is not JS

BABEL can compile JSX processes by using the react.createElement () syntax: JSX => react.createElement () => virtual DOM (JS object) => real DOM React React.createelement () accepts three arguments, the first for the label name, the second for the attribute, and the third for the content

CreateElement () determines whether a component or an HTML tag is uppercase. React dictates that the component must start with a uppercase letter, while HTML dictates that the tag must start with a lowercase letter

// The first parameter is tag'div'The tag name or List component // the second argument is: props // the third argument is child, and you can pass an array on the third argument, or.... on the third, fourth, or fifth argument The react. createElement('tag', null, [child1, chlild2, child3]) or react.createElement ('tag', { className: 'class1' }, child1, chlild2, child3)
Copy the code

Event synthesis mechanism

  • All events are mounted to document
  • Event is not native, it isSyntheticEventComposite event object
  • Unlike Vue events, and DOM events are also different

Why synthesize event mechanisms

  • Better compatibility and cross-platform, free from traditional DOM events
  • Mount to Document to reduce memory consumption and avoid frequent untying
  • Facilitate unified event management, such as transaction mechanism

SetState and batchUpdate(batch)

setState

  • Sometimes asynchronous (common use), sometimes synchronous (setTimeout, DOM event)
  • Sometimes merge (Object form), sometimes not (function form), which is easier to understand (Object. Assign). Functions cannot be merged

The core points

  • SetState main process
  • BatchUpdate mechanism
  • Transaction mechanism

Check if this.setState() is asynchronous, check if isBatchingUpdates are true and false

Which can hit the batchUpdate mechanism

  • The lifecycle (and the functions it calls)
  • Events registered in React (and functions it calls)
  • React can “manage” the entry

Which failed to hit the batchUpdate mechanism

  • SetTimeout setInterval etc. (and the function it calls)
  • Custom DOM times (and the functions it calls)
  • React “can’t handle” the entrance

Transaction transaction mechanism

Common basic interview questions

1. How do components communicate with each other

  • Parent and child component props
  • Custom events
  • Redux and Context, simple data uses Context

2. The JSX essence

JSX => react.createElement () => virtual DOM (JS object) => real DOM

3. ShouldComponentUpdate purposes

  • Performance optimization
  • Use this parameter together with immutable values. Otherwise, errors may occur

4. Redux single data stream

Redux single data flow diagram

5. SetState scenario

What is a pure function

  • Returns a new value with no side effects (no changes to other values)

7. Why use key for list rendering

  • Key must be used, and cannot be index or random
  • In the DIff algorithm, the tag and key are used to determine whether the node is the same
  • Reduce rendering times and improve rendering performance

8. Difference between function components and class components

  • Pure function, input props, output JSX
  • No power, no life cycle, no state
  • You cannot extend other methods

9. How to use asynchronous components

  • Loading large components
  • React.lazy
  • React.Suspense

10. Multiple components have common logic. How to separate them

  • High-level component HOC
  • Render Props

11. How to configure lazy loading on the react-router

As mentioned above…

12. What’s the difference between PureComponent

  • ShouldComponentUpdate implements shallow comparisons
  • Optimize performance
  • But use it in conjunction with immutable values

React events and DOM events

  • All events are mounted to document
  • Events are not native, but syntheticEvents synthesize event objects

14.React performance optimization

  • Add Key to render list
  • Custom events and DOM events are destroyed in time
  • Use asynchronous components wisely
  • Reduce the number of times you bind this
  • ShouldComponentUpdate, PureComponent, and Memo should be used properly
  • Use ImmutableJS properly
  • Webpack level optimization
  • The general front end can be optimized, such as lazy loading of pictures
  • Using SSR

React vs. Vue

The same

  • Both support componentization
  • It’s all data-driven views
  • We’re using VDOM to manipulate DOM

The difference between

  • React uses JSX to embrace JS and Vue uses templates to embrace HTML
  • React functional programming, Vue declarative programming
  • React is more self-reliant, Vue gives you what you want

JS basics – Variable types and calculations

typeofCan determine which types

  • Identify all types
  • Identify the function
  • Check whether it is a reference type, return object, cannot be further subdivided

2. When to use= = =When to use= =

3. The difference between value types and reference types

Reference types are essentially the same memory address. For performance reasons, JS objects use reference types. To avoid this situation, deep copy is required

Common value types: undefined, String, Bool, Symbol(‘s’) Common reference types: Object, Array, null(pointing to an empty address) Special reference types: function

4. Variable calculation

String splicing

5. Write deep copies by hand

Funciton deepClone (obj = {}) {// Determine whether a deep copy is required, not objects and arraysif(typeof obj ! = ='object' || obj == null) {
        return obj
    }
    letResult // Determines whether it is an arrayif (obj instanceof Array) {
        result = []
    } else{result = {}} // iterate over the objectfor (let key inObj) {// Ensure that key is not an attribute of the stereotypeif(obj. HasOwnProperty (key)) {// result[key] = deepClone(obj[key])}}return result
}
Copy the code

JS Basics – Prototypes and prototype chains

JS is a prototype-based inheritance language, and PS: Class extends is essentially a prototype-chain inheritance

1. How to determine if a variable is an array?

a instanceof Array
Copy the code

2. Write a simple jQuery, consider plug-ins and extensibility

class jQuery {
    constructor (selector) {
        const result = document.querySelectorAll(selector)
        const length = result.length
        for (let i = 0; i < length; i++) {
            this.[i] = result[i]
        }
        this.length = length
    }
    get (index) {
        return this[index]
    }
    each (fn) {
        for (let i = 0; i < this.length; i++) {
            const elem = this[i]
            fn(elem)
        }
    }
    on (type, fn) {
        return this.each(elem => {
            elem.addEventListener(type, fn, false} // jQuery.prototype.dialog =function(info) {alert(info)} class MyJQuery extends jQuery {constructor (selector) {super(selector)}...... }Copy the code

3. How to understand the prototypical nature of class?

  • Diagrams of prototypes and prototype chains
  • Execution rules for properties and methods

Supplementary knowledge – Defining a class

Constructor (old) {this.old = old}eat () {
        consoloe.log('eating'}} class Student extends People {constructor(name, number, constructor) Old) {super(old) // Pass the variable to the parent class and execute this.name = name this.number = number}sayHi () {
        console.log(this.name, this.number)
    }
}
const me = new Student('Ming'Console.log (me.name) // => console.sayhi () // => console.log(me.name) // => console.sayhi ()'function'
typeof Student => 'function'Prototype => People me.__proto === Student. Prototype => People me.__proto === Student.trueCongruence means the same address is referencedCopy the code
  • Each instance has an implicit stereotype__proto__
  • Each class has an explicit stereotypeprototype
  • The implicit stereotype of the instance points to the explicit stereotype corresponding to the class

Prototype-based execution rules

  • Searches in their own properties and methods are preferred
  • If you can’t find it, go automatically__proto__Implicit archetype lookup

Supplementary knowledge – Type judgment instanceof

How Instanceof works: You work your way up the hierarchy of __proto__ implicit archetypes

Class me instanceof Student //true
me instanceof People  // true
me instanceof Object  // true[] instanceof Array //true
[] instanceof Object  // true`

{} instanceof Object  // true`
Copy the code

Prototype chain

When extend is inherited, the parent class is instantiated once, and all have implicit stereotypes__proto__

Class student.prototype.__proto__ people.prototype console.log(people.prototype === Student.prototype.__proto__) ==>true
Copy the code

HasOwnProperty () inherits from Object, hasOwnProperty(functionName) => false HasOwnProperty () property name is true if inherited or owned

JS basics – scopes and closures

1. How to value different application scenarios of this?

  • As a general function
  • Use call Apply Bind to change the this reference
  • Called as an object method
  • Called in the class method
  • The arrow function always takes this of the parent scope

2. Write bind by hand

Function.prototype.bind1 = function() {/ / an Array parameter apart for const args = Array. The prototype. Slice. The call (the arguments) / / for this first (Array) const that = args. The shift () / / Delete and return the first item of array // get fn1.bind(...) Fn1 const self = this // returns a functionreturn function () {
        return self.apply(that, args)
    }
}
Copy the code

3. The application scenarios of closures in actual development are illustrated with examples

  • Hide data and only provide APIS, such as a simple cache tool

Additional knowledge – scope and free variables

scope

  • Global scope
  • Function scope
  • Block-level scopes (new in ES6)

Free variables

  • A variable is not defined in the current scope, but is used
  • Search through the upper scope, layer by layer, until you find it
  • If it is not found in the global scope, an error is reportedxx is not defined

Additional knowledge – closures

The special case of scope application has two manifestations:

  • Functions are passed as arguments
  • Function as the return value
  • The search for a function’s free variables is done at the function definition, in the parent scope, not at the execution place

100 will be printed on both the left and right

Supplementary knowledge – this

What is the value of this in each scenario that is determined when the function is executed, not when the function definition is defined

  • As a general function
  • Use call Apply Bind to change the this reference
  • Called as an object method
  • Called in the class method
  • The arrow function always takes this of the parent scope

Call is to execute directly, bind is to return a new function to execute

JS Base – events

Write a generic binding event

function bindEvent (elem, type, fn) {
    elem.addEventListener(type, fn)
}
Copy the code

Promise images lazy loading

function loadImg (src) {
    var promise = new Promise(function (resolve, reject) {
        var img = document.createElement('img')
        img.onload = function () {
            resolve(img)
        }
        img.onerror = function () {
            reject('Image load failed')
        }
        img.scr = src
    })
    retrun promise
}
var result = loadImg('www.baidu.com')
Copy the code