Performance optimization
Performance optimization is always the focus of the interview, and performance optimization is even more important for React
- Used in the page
setTimout()
,addEventListener()
And so on, in timecomponentWillUnmount()
The destruction of - Using asynchronous components
- use
React-loadable
Dynamically 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 component
PureComponent
, 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
- Parent components communicate via properties and props
- Communicate through context
- 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()
- Immutable values
- It may be an asynchronous update
- 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()
:class
The 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 returnedbool
Type of result if returnedtrue
Component updates normally, if returnedfalse
Components 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:
- The component receives parameters from the parent component;
- Only the parent component
render()
If executed, the life cycle of the child component is executed; - If the component first exists in the parent component, it is not executed;
- 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
- use
shouldComponentUpdate()
Prevent pages from rendering unnecessarily
# Performance optimization with lifecycle
shouldComponentUpdate () {
if(nextProps.content ! == this.props.content) {return true;
}
return false;
}
Copy the code
- Ajax requests initial page data
componentDidMount()
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:
- The parent component overflow: Hidden, but the child component wants to show;
- The z-index of the parent component is too small;
- 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
- dispatch(action)
- Reducer to produce newState because
- 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)
- Traverse Tree1, traverse Tree2
- The sorting
- 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)
- Compare only the same level, not across levels
- If the tag is different, delete it and rebuild it
- 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 – React
this.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 is
SyntheticEvent
Composite 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
typeof
Can 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 stereotype
prototype
- 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 reported
xx 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