current position:Home>JavaScript basics summary

JavaScript basics summary

2021-08-27 08:21:46 Beginner's self

JavaScript Basic knowledge summary

1. JavaScript brief introduction

  • JavaScript At first, it was a language specially designed for browsers , But now it's also used in many other environments .
  • Now ,JavaScript Has become associated with HTML/CSS Fully integrated , The most widely used browser language .
  • There are many other languages that can be “ compile ” become JavaScript, These languages also provide more functions . It's best to understand these languages , At least I have mastered JavaScript Then we'll have a general understanding of .

2. Variable

We can use var、let or const Declare variables to store data .

  • let — Modern variable declarations .
  • var — The old way of variable declaration . In general , We won't use it anymore . however , We will be in Old time "var" Chapter introduction var and let Subtle differences , In case you need them .
  • const — Be similar to let, But the value of the variable cannot be modified .

Variables should be named in a way that makes it easy to understand what is inside the variable .

3. data type

JavaScript There are eight basic data types in ( Translation notes : The first seven are basic data types , Also called primitive type , and object Is a complex data type ).

  • number For any type of number : Integer or floating point number , stay ±(253-1) Range of integers .
  • bigint An integer of any length .
  • string For string : A string can contain 0 Characters or more , So there's no single character type .
  • boolean be used for true and false.
  • null For unknown value —— only one null Independent type of value .
  • undefined For undefined values —— only one undefined Independent type of value .
  • symbol Used for unique identifier .
  • object For more complex data structures .

We can go through typeof Operator to see the type of data stored in the variable .

  • Two forms :typeof x perhaps typeof(x).
  • Returns the type name as a string , for example "string".
  • typeof null Returns the "object" —— This is a JavaScript A programming language error , In fact, it's not a object.

4. Type conversion

There are three common type conversions : Convert to string type 、 Convert to number Type and convert to boolean type .

String conversion —— The conversion occurs when the content is output , It can also be done through String(value) Make an explicit conversion . Of the original type value string Type conversion is usually obvious .

Digital conversion —— Conversion occurs during arithmetic operations , It can also be done through Number(value) Make an explicit conversion .

Digital conversion follows the following rules :

Boolean conversion follows the following rules : Boolean conversion —— Conversion occurs when a logical operation is performed , It can also be done through Boolean(value) Make an explicit conversion .

Yes undefined When performing digital conversion , The output is NaN, Instead of 0. Most of the above rules are easy to understand and remember . Notable examples of people's common mistakes are the following :

  • Yes "0" And strings with only spaces ( such as :" ") During Boolean conversion , The output is true.

5. Comparison of values

  • Comparison operators always return Boolean values .
  • String comparison , According to “ The dictionary ” Compare sizes sequentially character by character .
  • When comparing different types of values , They will first be converted into numbers ( Strict equality checks are not included ) Then compare .
  • In non strict equality == Next ,null and undefined Equal and not equal to any other value .
  • In the use of > or < When comparing , Note that the variable may be null/undefined The situation of . It is better to check whether the variable is equal to null/undefined.

6. Null merge operator '??'

  • Null merge operator ?? Provides a way to select the first one from the list “ Defined ” An easy way to value .

It is used to assign default values to variables :

//  When  height  The value of is  null  or  undefined  when , take  height  Is set to  100
height = height ?? 100;
 Copy code 
  • ?? Operators have a very low priority , Only slightly higher ? and =, So when using it in expressions, consider adding parentheses .
  • If you don't explicitly add parentheses , It can't be associated with || or && Use it together .

7. loop :while and for

We learned three cycles :

  • while —— Check the conditions before each iteration .
  • do..while —— Check the conditions after each iteration .
  • for (;;) —— Check the conditions before each iteration , You can use other settings .

Usually use while(true) To construct the “ Infinite ” loop . This cycle is the same as other cycles , Both can pass break Command to terminate .

If we don't want to do anything in the current iteration , And want to move to the next iteration , Then you can use continue Instructions .

break/continue break Out of the loop ,continue Jump out of this cycle .break Jump out of a nested loop , The only way to go outside .

8. function

The function is declared as follows :

function name(parameters, delimited, by, comma) {
  /* code */
}
 Copy code 
  • The value passed to the function as an argument , Will be copied to the function's local variables .
  • Function can access external variables . But it only works from the inside out . The code outside the function does not see the local variables inside the function .
  • Function can return value . If there is no return value , The result it returns is undefined.

In order to make the code simple and easy to understand , It is recommended to mainly use local variables and parameters in functions , Not external variables .

Compared to a function that does not take parameters but modifies external variables as side effects , To obtain parameters 、 Functions that use parameters and return results are easier to understand .

Function name :

  • The function name should clearly describe the function's function . When we see a function call in the code , A good function name can let us know immediately what the function is , What will be returned .
  • A function is a behavior , So function names are usually verbs .
  • There are many excellent prefixes for function names , Such as create…、show…、get…、check… wait . Use them to hint at the function's purpose .

9. Function expression

var functionName = function(arg0, arg1, arg2) {
    // The body of the function 
}
 Copy code 
  • Function is value . They can be assigned anywhere in the code , Copy or claim .
  • If a function is declared as a separate statement in the main code stream , It is called a “ Function declaration ”.
  • If the function was created as part of an expression , Then we call it “ Function expression ”.
  • Before code block execution , The internal algorithm will first process the function declaration . So the function declaration is visible anywhere in the code block it is declared .
  • The function expression is not created until the execution process arrives .

in the majority of cases , When we need to declare a function , Function declaration is best used , Because functions are also visible before they are declared . This gives us more flexibility in code organization , It also makes the code more readable .

therefore , Only if the function declaration is not suitable for the corresponding task , Only function expressions should be used .

10. Arrow function , Basic knowledge of

For a function of one line of code , Arrow function is quite convenient . There are two kinds of it :

  1. Without curly braces :(...args) => expression — On the right is an expression : Function to evaluate an expression and return its result .
  2. Curly bracket :(...args) => { body } — Curly braces allow us to write multiple statements in a function , But we need to explicitly return To return something .

11. object

Objects are associative arrays with some special properties .

They store properties ( Key value pair ), among :

  • The key of the property must be a string or symbol( It's usually a string ).
  • Values can be of any type .

We can use the following methods to access properties :

  • Dot notation : obj.property.
  • square brackets obj["property"], Square brackets allow you to get keys from variables , for example obj[varWithKey].

Other operating :

  • Delete attribute :delete obj.prop.
  • Check whether the properties of the given key exist :"key" in obj.
  • Traversing objects :for(let key in obj) loop .

What we learn in this chapter is called “ Common object (plain object)”, Or the object .

JavaScript There are many other types of objects in :

  • Array For storing ordered data sets ,
  • Date Used to store time date ,
  • Error Used to store error messages .
  • …… wait .

They have their own special characteristics , We will learn later that . Sometimes people say “Array type ” or “Date type ”, But they are not of their own type , It belongs to an object type, that is “object”. They treat in different ways “object” Made some extensions .

12. Object reference and copy

Objects are assigned and copied by reference . let me put it another way , A variable does not store “ The value of the object ”, It's a value “ quote ”( Memory address ). therefore , When copying such variables or passing them as function parameters , What is copied is a reference , Not the object itself .

All operations through copied references ( Such as adding 、 Delete attribute ) All act on the same object .

In order to create “ Real copy ”( A clone ), We can use Object.assign To do the so-called “ Shallow copy ”( Nested objects are copied by reference ) Or use “ Deep copy ” function , for example  _.cloneDeep(obj).

13. Object methods ,"this"

  • Functions stored in object properties are called “ Method ”.
  • Method allows an object to perform operations like object.doSomething() In this way “ operation ”.
  • Method can reference an object as this.
  • this The value of is obtained when the program runs .
  • When a function is declared , Probably used this, But this this Only when the function is called will it have a value .
  • You can copy functions between objects .
  • With “ Method ” When calling a function with the syntax of :object.method(), During the call this The value is object.

Note that the arrow function has something special : They don't have this. Accessed inside the arrow function this All from outside .

14. Optional chain "?."

Optional chain ?. There are three forms of grammar :

  1. obj?.prop —— If obj To be is to return obj.prop, Otherwise return to undefined.
  2. obj?.[prop] —— If obj To be is to return obj[prop], Otherwise return to undefined.
  3. obj.method?.() —— If obj.method If it exists, call obj.method(), Otherwise return to undefined.

As we can see , These grammatical forms are very simple and direct to use .?. Check that the left part is null/undefined, If not, continue the operation .

?. Chains allow us to safely access nested properties .

however , We should use... With caution ?., Only use when the left part doesn't exist and doesn't matter . To ensure that there are programming errors in the code , And it won't hide from us .

15. Symbol type

Symbol Is the basic type of unique identifier

Symbol Is to use with optional description (name) Of Symbol() Call to create .

Symbol Always different values , Even if they have the same name . If we want the same name Symbol equal , Then we should use the global registry :Symbol.for(key) return ( If necessary, create ) One by key As a global name Symbol. Use Symbol.for Multiple calls key same Symbol when , The return is the same Symbol.

Symbol There are two main usage scenarios :

  1. “ hide ” Object properties . If we want to “ Belong to ” Add a property to another script or library object , We can create one Symbol And use it as the key of the attribute .Symbol Properties do not appear in for..in in , Therefore, it will not be accidentally processed with other attributes . also , It will not be accessed directly , Because the other script doesn't have ours symbol. therefore , This property will be protected , Prevent accidental use or rewriting .

So we can use Symbol attribute “ Secretly ” Hide something in the object we need , But you can't see it anywhere else .

  1. JavaScript Many systems are used Symbol, these Symbol It can be used as Symbol.* visit . We can use them to change some built-in behavior . for example , Later in this tutorial , We will use Symbol.iterator To carry out   iteration   operation , Use Symbol.toPrimitive To set up   Conversion of the original value of the object   wait .

Technically speaking ,Symbol No 100% Hidden . There's a built-in method  Object.getOwnPropertySymbols(obj)  Allow us to get all Symbol. There's another one called  Reflect.ownKeys(obj)  The method of can return the of an object all key , Include Symbol. So they are not really hidden . But most libraries 、 Neither built-in methods nor syntax structures use these methods .

16. Numeric type

Write numbers with many zeros :

  • take "e" and 0 The quantity of is appended to the number . It's like :123e6 And 123 Followed by 6 individual 0 identical .
  • "e" The following negative number will divide the number by 1 Followed by a given number of zeros . for example 123e-6 Express 0.000123(123 One millionth of ).

For different digital systems :

  • It can be directly in hexadecimal (0x), octal (0o) And binary (0b) Write numbers to the system .
  • parseInt(str,base) The string str Resolves to in a given base An integer in a digital system ,2 ≤ base ≤ 36.
  • num.toString(base) Convert a number to a number in a given base A string in a digital system .

To put 12pt and 100px Such values are converted to numbers :

  • Use parseInt/parseFloat Conduct “ soft ” transformation , It reads numbers from strings , Then return to what happened error The value that can be read before .

decimal :

  • Use Math.floor,Math.ceil,Math.trunc,Math.round or num.toFixed(precision) Round off .
  • Be sure to remember that using decimals will lose precision .

More mathematical functions :

  • Please check... If necessary Math object . This library is very small , But it can meet the basic needs .

17. character string

  • Yes 3 Two types of quotation marks . Backquotes allow strings to span multiple lines and can be used ${…} Embed an expression in a string .
  • JavaScript The string in is UTF-16 code .
  • We can use things like \n Such special characters or by using \u... To operate their unicode Insert characters .
  • When getting characters , Use [].
  • Get substring , Use slice or substring.
  • The size of the string / Lowercase conversion , Use :toLowerCase/toUpperCase.
  • Error finding substring , Use indexOf or includes/startsWith/endsWith Make a simple check .
  • Use... When comparing strings by language localeCompare, Otherwise, it will be compared by character code .

There are several other useful string methods :

  • str.trim() —— Delete the space before and after the string (“trims”).
  • str.repeat(n) —— Duplicate string n Time .
  • …… For more details, see manual .

18. Array

Arrays are special objects , It is suitable for storing and managing orderly data items .

  • Statement :

    // square brackets ( Common use ) let arr = [item1, item2...];

    // new Array ( Extremely rare ) let arr = new Array(item1, item2...);

call new Array(number) Will create an array of the given length , But it doesn't contain any items .

  • length Property is the length of the array , To be exact , It is the index value of the last digit of the array plus one . It is automatically adjusted by the array method .
  • If we manually shorten length, Then the array will be truncated .

We can use arrays as double ended queues through the following operations :

  • push(...items) Add... At the end items term .
  • pop() Remove and return the element from the end .
  • shift() Remove and return the element from the header .
  • unshift(...items) Add... From the head end items term .

Traversing the elements of an array :

  • for (let i=0; i<arr.length; i++) — Run fastest , Compatible with older browsers .
  • for (let item of arr) — Modern grammar , Only access items.
  • for (let i in arr) — Never use this .

When comparing arrays , Do not use == Operator ( Of course, don't use > and < Equal operator ), Because they don't do special processing on arrays . They usually deal with arrays as they do with arbitrary objects , This is not usually what we want .

however , We can use for..of Loop to compare arrays item by item .

19. Array methods

Array method memo :

  • add to / Remove elements :

    • push(...items) —— Add an element to the tail ,
    • pop() —— Extract an element from the tail ,
    • shift() —— Extract an element from the head ,
    • unshift(...items) —— Add an element to the head end ,
    • splice(pos, deleteCount, ...items) —— from pos To delete deleteCount Elements , And insert items.
    • slice(start, end) —— Create a new array , From the index start To the index end( But does not include end) Copy the elements into .
    • concat(...items) —— Returns a new array : Copy all elements of the current array , And add items. If items Any item in is an array , Then take its elements .
  • Search element :

    • indexOf/lastIndexOf(item, pos) —— From the index pos Begin your search item, If found, the index of the item will be returned , Otherwise return to -1.
    • includes(value) —— If the array has value, Then return to true, Otherwise return to false.
    • find/filter(func) —— adopt func Filter element , Return to make func return true First value of / All worth .
    • findIndex and find similar , But return the index instead of the value .
  • Traversing elements :

    • forEach(func) —— Call... For each element func, Don't return anything .
  • Convert array :

    • map(func) —— Call... On each element according to func Create a new array as a result of .
    • sort(func) —— The array is modified (in-place) Sort , Then go back to it .
    • reverse() —— In situ (in-place) Inversion array , Then go back to it .
    • split/join —— Converts a string to an array and returns .
    • reduce/reduceRight(func, initial) —— By calling... On each element func Calculate a single value on an array , And pass intermediate results between calls .
  • other :

    • Array.isArray(arr) Check arr Is it an array .

Please note that ,sort,reverse and splice Method modifies the array itself .

These are the most common methods , They cover 99% The use case . But there are a few others :

And map similar , Call the function... On each element of the array fn. If anything / All the results are true, Then return to true, Otherwise return to false.

The behavior of these two methods is similar to || and && Operator : If fn Returns a true value ,arr.some() Return immediately true And stop iterating over the remaining array items ; If fn Returns a false value ,arr.every() Return immediately false And stop iterating over the remaining array items .

We can use every To compare arrays :

function arraysEqual(arr1, arr2) {
  return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
}

alert( arraysEqual([1, 2], [1, 2])); // true
 Copy code 

About the complete list , see also manual .

20. Iterable object( Iteratable object )

Can be applied for..of The object of is called Iterable .

  • Technically , Iteratable objects must implement Symbol.iterator Method .

    • objSymbol.iterator The result is called iterator (iterator). It handles further iterations .
    • An iterator must have next() Method , It returns a {done: Boolean, value: any} object , here done:true Indicates the end of the iteration , otherwise value Is the next value .
  • Symbol.iterator The method will be for..of Automatically call , But we can also call it directly .

  • Built in iteratable objects such as strings and arrays , It's all done Symbol.iterator.

  • String iterators can identify proxy pairs (surrogate pair).( Translation notes : Agent right, that is UTF-16 Extended characters .)

There are index properties and length The object of the property is called Class array object . This object may also have other properties and methods , But there are no built-in methods for arrays .

If we study the specification carefully —— You will find that most built-in methods assume that they need to deal with iteratable objects or class array objects , instead of “ real ” Array , Because it's more abstract .

Array.from(obj[, mapFn, thisArg]) An iteratable object or class array object obj Convert to a real array Array, Then we can apply array methods to it . Optional parameters mapFn and thisArg Allows us to apply functions to each element .

21. Map and Set( Maps and sets )

Map —— Is a collection of data items with keys .

The methods and properties are as follows :

  • new Map([iterable]) —— establish map, Optional with [key,value] Right iterable( For example, an array of ) To initialize .
  • map.set(key, value) —— Store the value according to the key .
  • map.get(key) —— Returns the value according to the key , If map There is no corresponding key, Then return to undefined.
  • map.has(key) —— If key To be is to return true, Otherwise return to false.
  • map.delete(key) —— Delete the value of the specified key .
  • map.clear() —— Empty map .
  • map.size —— Returns the current number of elements .

And ordinary objects Object The difference between :

  • Any key 、 Objects can be used as keys .
  • There are other convenient ways , Such as size attribute .

Set —— Is a set of unique values .

Methods and properties :

  • new Set([iterable]) —— establish set, Optional with iterable( For example, an array of ) To initialize .
  • set.add(value) —— Add a value ( If value If it exists, it will not be modified ), return set In itself .
  • set.delete(value) —— Delete value , If value If it exists when this method is called, it returns true , Otherwise return to false.
  • set.has(value) —— If value stay set in , return true, Otherwise return to false.
  • set.clear() —— Empty set.
  • set.size —— Number of elements .

stay Map and Set Iterations in are always carried out in the order of value insertion , So we can't say that these sets are disordered , But we can't reorder elements , Nor can you get elements directly by their number .

22. WeakMap and WeakSet( Weak mappings and weak sets )

WeakMap Is similar to the Map Set , It only allows objects as keys , And once they cannot be accessed by other means , They are deleted together with their associated values .

WeakSet Is similar to the Set Set , It only stores objects , And once they cannot be accessed by other means , It will be deleted .

Neither of them supports methods and properties that reference all keys or their counts . Only a single operation is allowed .

WeakMap and WeakSet be used as “ The main ” Object storage “ auxiliary ” data structure . Once the object is deleted from main memory , If the object is only used as WeakMap or WeakSet Key , Then it will be automatically cleared .

23. Deconstruct assignment

  • Deconstruction assignment can immediately map an object or array to multiple variables .

  • The complete syntax for deconstructing objects :

    let {prop : varName = default, ...rest} = object

This means that the property prop Will be assigned to the variable varName, Without this property , The default value will be used default.

Object properties without corresponding mapping will be copied to rest object .

  • The complete syntax for deconstructing arrays :

    let [item1 = default, item2, ...rest] = array

The first element of the array is assigned to item1, The second element is assigned to item2, All the remaining elements are copied to another array rest.

  • From nested arrays / It is also possible to extract data from objects , At this time, the left side of the equal sign must have the same structure as the right side of the equal sign .

24. Date and time

  • stay JavaScript in , Date and time use Date Object to represent . We can't just create dates , Or just create time ,Date Objects always create both at the same time .
  • Month from 0 Start counting ( Yes , January is 0).
  • One day of the week getDay() Also from 0 Start calculating (0 On behalf of Sunday ).
  • When an out of range component is set ,Date Will self calibrate . This is for Japan / month / The addition and subtraction of hours is very useful .
  • Dates can be subtracted , What you get is the difference between the two in milliseconds . Because when Date When converted to numbers ,Date The object is converted to a timestamp .
  • Use Date.now() You can get the timestamp of the current time faster .

Unlike other systems ,JavaScript The timestamp in is in milliseconds , Not seconds .

Sometimes we need more accurate time measurement .JavaScript There is no way to measure microseconds by itself ( One millionth of a second ), But most operating environments provide . for example : Browser has performance.now() Method to give the number of microseconds in milliseconds from page loading ( Three decimal places accurate to milliseconds ):

alert(`Loading started ${performance.now()}ms ago`);
//  Be similar to  "Loading started 34731.26000000001ms ago"
// .26  It represents microseconds (260  Microsecond )
//  Beyond the decimal point  3  The number of bits is precision error , Only the first three digits are correct 
 Copy code 

Node.js Yes microtime Modules and other methods . Technically speaking , Almost all devices and environments allow higher precision values , Just not through Date object .

25. JSON Method ,toJSON

  • JSON Is a data format , It has its own independent standards and libraries for most programming languages .
  • JSON Support object,array,string,number,boolean and null.
  • JavaScript Provide serialization (serialize) become JSON Methods JSON.stringify And analysis JSON Methods JSON.parse.
  • Both methods are supported for intelligent reading / Write the conversion function .
  • If an object has toJSON, Then it will be JSON.stringify call .

26. Recursion and stack

The term :

  • recursive Is a term for programming , Means calling a function from itself ( Translation notes : That is, self calling ). Recursive functions can be used to solve problems in a more elegant way .

When a function calls itself , We call it recursive procedure . Recursive Basics It is the function parameter that makes the task so simple that the function does not need to be called further .

for example , A linked list can be defined as a list referenced by an object ( or null) And the data structure .

list = { value, next -> list }
 Copy code 

image HTML Element tree or... In this chapter department Trees, etc , Essentially recursive : They have branches , And branches can have other branches .

Just as we are in the example sumSalary As seen in , You can use recursive functions to traverse them .

Any recursive function can be rewritten as an iteration ( Translation notes : That's circulation ) form . Sometimes this is what you need to do when optimizing your code . But for most tasks , Recursive methods are fast enough , And easy to write and maintain .

27. Rest Parameters and Spread grammar

When we see it in the code "..." when , It's either rest Parameters , Either it's spread grammar .

There is a simple way to distinguish them :

  • if ... Appears at the end of the function argument list , So it's going to be rest Parameters , It will collect the remaining parameters in the parameter list into an array .
  • if ... Appear in a function call or similar expression , Then it is spread grammar , It expands an array into a list .

Use scenarios :

  • Rest Parameter is used to create a function that can accept any number of parameters .
  • Spread Syntax is used to pass an array to a function that usually needs a list with many parameters .

Their presence helps us easily convert back and forth between lists and parameter arrays .

“ old type ” Of arguments( Class array and iteratable objects ) It can still help us get all the parameters in the function call .

28. Global object

  • Global objects contain variables that should be visible anywhere .
  • These include JavaScript Built in method of , for example “Array” And environment specific (environment-specific) Value , for example window.innerHeight — Window height in browser .
  • Global objects have a common name globalThis.
  • …… But it's more common to use “ old-fashioned ” Environment specific (environment-specific) Name , for example window( browser ) and global(Node.js).
  • Only if the value is really global for our project , Should be stored in a global object . And keep the number to a minimum .
  • In the browser , Unless we use modules, Otherwise use var Declared global functions and variables become properties of global objects .
  • To make our code future oriented and easier to understand , We should use a direct way to access the properties of global objects , Such as window.x.

29. Function object ,NFE

Functions are objects .

We introduced some of their properties :

  • name —— Function name . Usually taken from the function definition , But if the function name is not set in the function definition ,JavaScript Will try to guess a function name from the context of the function ( For example, take the assigned variable name as the function name ).
  • length —— The number of input parameters when defining a function .Rest Parameter does not participate in counting .

If a function is declared in the form of a function expression ( Not in the main code stream ), And with a name , Then it is called named function expression (Named Function Expression). This name can be used to make self calls inside the function , For example, recursive call, etc .

Besides , Functions can have additional properties . Many famous JavaScript Libraries take full advantage of this feature .

They create a “ Lord ” function , Then add a lot of other “ auxiliary ” function . for example ,jQuery The library creates a file called $ Function of .lodash Library create a _ function , Then add .add、.keyBy And other properties ( Want to know more about , Reference docs). actually , They do this to reduce pollution to global space , Such a library will have only one global variable . This reduces the possibility of naming conflicts .

therefore , A function itself can do a useful job , You can also include many other functions in your own properties .

29. "new Function" grammar

grammar :

let func = new Function ([arg1, arg2, ...argN], functionBody);
 Copy code 

For historical reasons , Parameters can also be given in the form of comma separators .

The following three statements have the same meaning :

new Function('a', 'b', 'return a + b'); //  Basic grammar 
new Function('a,b', 'return a + b'); //  Comma separated 
new Function('a , b', 'return a + b'); //  Separated by commas and spaces 
 Copy code 

Use new Function Functions created , its [[Environment]] Point to the global Lexical Environment , Not the external lexical environment of the function . therefore , We can't new Function Use external variables directly in . But that's a good thing , This helps to reduce the possibility of errors in our code . also , In terms of code architecture , Explicit use of parameter passing is a better way , And avoid the problem of conflict with the use of compression program .

30. Dispatch :setTimeout and setInterval

  • setTimeout(func, delay, ...args) and setInterval(func, delay, ...args) Methods allow us to delay Run in milliseconds func Once or in delay Run periodically in milliseconds func.
  • To cancel the execution of the function , We should call clearInterval/clearTimeout, And will setInterval/setTimeout The returned value is passed in as an input parameter .
  • Nested setTimeout Than setInterval It's more flexible to use , Allows us to set the time between executions more precisely .
  • Zero delay scheduling setTimeout(func, 0)( And setTimeout(func) identical ) Used to schedule calls that need to be executed as soon as possible , However, it will be called after the execution of the current script .
  • The browser will setTimeout or setInterval Five or more nested calls ( After five calls ) The minimum delay is limited to 4ms. This is a problem left over from history .

Please note that , All scheduling methods cannot Guarantee Exact delay .

for example , Timers in browsers can slow down for many reasons :

  • CPU overload .
  • The browser tab is in background mode .
  • Laptops are powered by batteries ( Translation notes : Using battery power will improve battery life at the cost of reduced performance ).

All these factors , The minimum timer resolution of the timer may be ( Minimum delay ) Add to 300ms even to the extent that 1000ms, The details shall be subject to the browser and its settings .

31. Decorator mode and forwarding ,call/apply

Decorator Is a wrapper around changing the behavior of functions . The main work is still done by this function .

Decorators can be thought of as objects that can be added to functions “features” or “aspects”. We can add one or more . And all this without changing its code !

In order to achieve cachingDecorator, We studied the following methods :

General purpose Call forwarding (call forwarding) It is usually used apply Accomplished :

let wrapper = function() {
  return original.apply(this, arguments);
};
 Copy code 

We can also see one Method borrowing (method borrowing) Example , That is, we get a method from an object , And in the context of another object “ call ” it . Take array methods and apply them to parameters arguments It's very common . Another way is to use Rest Parameter object , This object is a real array .

32. Function binding

Method func.bind(context, ...args) Return function func Of “ The binding of (bound) variant ”, It binds the context this And the first parameter ( If given ).

Usually we use bind To bind object methods this, So we can transfer them to other places for use . for example , Pass to setTimeout.

When we bind some parameters of an existing function , Bound ( Not very general ) Functions are called partially applied or partial.

When we don't want to repeat the same parameters over and over again ,partial Very useful . Like we have a send(from, to) function , And for our mission ,from It should always be the same , Then we can make a partial And use it .

33. Deep understanding of arrow functions

Arrow function :

  • No, this
  • No, arguments
  • Out of commission new To call
  • They don't either super, But we haven't learned it yet . We will be in Class inheritance Learn it in one chapter .

This is because , The arrow function is for those who do not have their own “ Context ”, But short code that works in the current context . And the arrow function does shine in this use scenario .

34. Prototype inheritance

  • stay JavaScript in , All objects have a hidden [[Prototype]] attribute , It's either another object , Either it's null.
  • We can use obj.proto Visit it ( A legacy of history getter/setter, There are other ways , Soon we'll talk about ).
  • adopt [[Prototype]] The referenced object is called “ Prototype ”.
  • If we want to read obj Or call a method , And it doesn't exist , that JavaScript Will try to find it in the prototype .
  • Write / The deletion operation is performed directly on the object , They don't use prototypes ( Suppose it is a data attribute , No setter).
  • If we call obj.method(), and method From the prototype ,this Will still reference obj. therefore , Method is always used with the current object , Even if the method is inherited .
  • for..in The loop iterates over itself and inherited properties . All the other keys / The value acquisition method works only on the object itself .

35. F.prototype

It's all very simple , Just remember a few key points and you can grasp them clearly :

  • F.prototype attribute ( Don't associate it with [[Prototype]] Confused ) stay new F Is the name of the new object when called [[Prototype]] assignment .
  • F.prototype The value of is either an object , Either it's null: Other values don't work .
  • "prototype" Property only sets a constructor (constructor function), And pass new Invocation time , Has this special influence .

On regular objects ,prototype Nothing special :

let user = {
  name: "John",
  prototype: "Bla-bla" //  Here are just common properties 
};
 Copy code 

By default , All functions have F.prototype = {constructor:F}, So we can access its "constructor" Property to get the constructor of an object .

36. The original prototype

  • All built-in objects follow the same pattern (pattern):

    • Methods are stored in prototype in (Array.prototype、Object.prototype、Date.prototype etc. ).
    • The object itself only stores data ( Array elements 、 Object properties 、 date ).
  • The raw data type also stores the method in the wrapper object prototype in :Number.prototype、String.prototype and Boolean.prototype. Only undefined and null No wrapper object .

  • Built in prototypes can be modified or populated with new methods . But it is not recommended to change them . The only permissible situation may be , When we add one that has not been JavaScript Engine support , But it has been added JavaScript The new standard of the specification , It is possible to allow this .

37. Prototype method , No, proto The object of

Modern ways to set up and directly access prototypes are :

If you want to put a user generated key into an object , So the built-in proto getter/setter It's not safe . Because the user may enter "proto" As key , This will lead to a error, Although we hope this problem will not have a big impact , But it usually has unpredictable consequences .

therefore , We can use Object.create(null) Create one without proto Of “very plain” object , Or stick to such scenarios Map Objects will do .

Besides ,Object.create Provides a simple way to shallow copy all descriptors of an object :

let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
 Copy code 

Besides , We also made it clear proto yes [[Prototype]] Of getter/setter, Just like other methods , It is located in Object.prototype.

We can go through Object.create(null) To create objects without prototypes . Such objects are used as “pure dictionaries”, For them , Use "proto" As a key, there is no problem .

Other methods :

All methods that return object properties ( Such as Object.keys And others )—— All back to “ Oneself ” Properties of . If we want to inherit them , We can use for...in.

38. Class Basic grammar

The basic class syntax looks like this :

class MyClass {
  prop = value; //  attribute 

  constructor(...) { //  Constructors 
    // ...
  }

  method(...) {} // method

  get something(...) {} // getter  Method 
  set something(...) {} // setter  Method 

  [Symbol.iterator]() {} //  There is a calculation name (computed name) Methods ( Here is  symbol)
  // ...
}
 Copy code 

Technically ,MyClass It's a function ( We offer as constructor the ), and methods、getters and settors It's all written MyClass.prototype.

39. Class inheritance

  1. Want to extend a class :class Child extends Parent:
  • It means Child.prototype.proto It will be Parent.prototype, So the method will be inherited .
  1. Rewrite a constructor:
  • In the use of this Before , We have to Child Of constructor Lieutenant general, father constructor Called as super().
  1. Rewrite a method :
  • We can do it in one Child Method used in super.method() To call Parent Method .
  1. Inside :
  • Method is internal [[HomeObject]] Property with their classes in mind / object . This is it. super How to resolve the parent method .
  • therefore , Put one with super It is not safe to copy methods from one object to another .

Add :

  • Arrow function does not have its own this or super, So they can be integrated into the nearest context , As transparent .

40. Static properties and static methods

Static methods are used to implement functions belonging to the entire class . It has nothing to do with concrete class instances .

for instance , A method for comparison Article.compare(article1, article2) Or a factory (factory) Method Article.createTodays().

In this kind of life , They are all used as keywords static It's marked .

Static attributes are used when we want to store class level data , Instead of binding to an instance .

The syntax is shown below :

class MyClass {
  static property = ...;

  static method() {
    ...
  }
}
 Copy code 

Technically speaking , Static declarations are the same as assigning values directly to the class itself :

MyClass.property = ...
MyClass.method = ...
 Copy code 

Static properties and methods are inheritable .

about class B extends A, class B Of prototype Yes A:B.[[Prototype]] = A. therefore , If a field is in B Not found in , Will continue in A Search for .

41. Private and protected properties and methods

Object oriented programming (OOP) for , The division between internal and external interfaces is called encapsulation .

It has the following advantages :

Protect users , So that they don't hurt themselves by mistake

Imagine , A group of developers are using a coffee machine . This coffee machine is made of “ The best coffee machine ” Made by the company , Work well , But the protective cover was removed . So the internal interface is exposed .

All developers are civilized —— They use the coffee machine as expected . But one of them , John , He thinks he is the smartest person , And made some adjustments to the interior of the coffee machine . However , The coffee machine broke down in two days .

It's definitely not John's fault , It's the fault of the man who took off the protective cover and let John operate .

Programming is the same . If one class Users want to change things that are not intended to be changed from the outside —— The consequences are unpredictable .

Supportability

The programming situation is much more complicated than the coffee machine in real life , Because we don't just buy once . We also need to constantly develop and improve the code .

If we strictly define the internal interface , So this class Developers are free to change their internal properties and methods , You don't even need to notify the user .

If you are like this class The developer of the , Then you'll be glad to know that it's safe to rename private variables , Its parameters can be changed or even deleted , Because no external code depends on them .

For users , When a new version comes out , The interior of the application may have been overhauled , But if the external interfaces are the same , It's still easy to upgrade .

Hide complexity

People like to use simple things . At least from the outside . What's inside is another matter .

Programmers are no exception .

When implementation details are hidden , And provides a simple and documented external interface , It's always convenient .

To hide the internal interface , We use protected or private properties :

  • Protected fields are marked with _ start . This is a well-known agreement , Not enforced at the language level . Programmers should only access through its classes and classes inherited from it to _ The first field .
  • Private fields with # start .JavaScript Make sure we can only access them from inside the class .

at present , The support for private fields in various browsers is not very good , But you can use polyfill solve .

42. Class inspection :"instanceof"

Let's summarize what we know about type checking :

When we use the hierarchy of classes (hierarchy), And want to check this class , Also consider inheritance , In this case instanceof Operators are really good . As we can see , Technically speaking ,{}.toString It's a kind of “ More advanced ” typeof.

43. Mixin Pattern

Mixin — Is a general object-oriented programming term : A class that contains methods of other classes .

Some other programming languages allow multiple inheritance .JavaScript Multiple inheritance is not supported , But you can do this by copying the method into the prototype mixin.

We can use mixin As a way of adding multiple behaviors ( For example, the event handling mentioned above ) To extend the methods of the class .

If Mixins Method of an existing class was accidentally overridden , Then they may become a conflict point . therefore , Usually you should think carefully mixin Naming method of , To minimize the possibility of such conflict .

44. Error handling ,"try..catch"

try..catch Structure allows us to deal with problems that occur during execution error. Literally , It allows the “ Try ” Run the code and “ Capture ” Possible errors .

The grammar is as follows :

try {
  //  Execute the code here 
} catch(err) {
  //  If an error occurs , Jump here 
  // err  It's a  error  object 
} finally {
  //  Anyway, it will be in  try/catch  After performing 
}
 Copy code 

There may not be catch Part or nothing finally, therefore try..catch or try..finally All available .

Error Object contains the following properties :

  • message — Human readable error Information .
  • name — have error Name string (Error The name of the constructor ).
  • stack( There is no standard , But there was good support )— Error Call stack when occurs .

If we don't need error object , We can do that by using catch { instead of catch(err) { To omit it .

We can also use throw Operator to generate custom error. Technically speaking ,throw The argument can be anything , But it is usually inherited from the built-in Error Class error object . In the next chapter, we will introduce the extension in detail error.

Throw again (rethrowing) Is an important mode of error handling :catch Blocks usually expect and know how to handle a particular error type , So it should throw out what it doesn't know again error.

Even if we don't try..catch, Most execution environments also allow us to set up “ overall situation ” Error handler to capture “ Fall out (fall out)” Of error. In the browser , Namely window.onerror.

45. Customize Error, Expand Error

  • We can normally start from Error And other built-in error Class ,. We just need to pay attention to name Properties and don't forget to call super.
  • We can use instanceof To check for specific error. But sometimes we have from third-party libraries error object , And there is no simple way to get its class here . Then you can put name Property is used for this class of checks .
  • Packaging anomaly is a widely used technology : Used to handle low-level exceptions and create high-level exceptions error Not all kinds of low-level error Function of . In the example above , Low level exceptions sometimes become properties of the object , for example err.cause, But it's not strictly required .

46. Promise chain

If .then( or catch/finally Fine ) The handler (handler) Return to one promise, Then the rest of the chain will wait , Until its state changes to settled. When it is settled after , Its result( or error) Will be passed on further .

This is a complete flow chart :

47. Use promise Error handling

  • .catch Handle promise All kinds of error: stay reject() In the call , Or in the handler (handler) Thrown in (thrown)error.
  • We should have .catch Exactly where we want to deal with error, And know how to deal with these error The place of . The handler should analyze error( You can customize error Class to help analyze ) And throw the unknown... Again error( Maybe they are programming errors ).
  • If there is no way from error If you recover from , Don't use .catch It's fine too .
  • In any case, we should have unhandledrejection Event handler ( For browsers , And Simulation of other environments ), To track unprocessed error And tell the user ( Maybe our server ) relevant information , So that our application will never “ Die ”.

Supplementary content

Fetch Error handling examples

Let's improve user loading (user-loading) Example error handling .

When the request cannot be sent ,fetch reject Returns the promise. for example , Remote server cannot access , perhaps URL abnormal . But if the remote server returns a response error 404, Even a mistake 500, These are considered legitimate responses .

If in (*) That's ok , The server returned an error 500 Non - JSON(non-JSON) What to do with the page ? Without this user ,GitHub Returns an error 404 What should I do with my page ?

fetch('no-such-user.json') // (*)
  .then(response => response.json())
  .then(user => fetch(`https://api.github.com/users/${user.name}`)) // (**)
  .then(response => response.json())
  .catch(alert); // SyntaxError: Unexpected token < in JSON at position 0
  // ...
 Copy code 

up to now , The code attempts to JSON Load response data in format , But in any case, it will fail because of grammatical errors . You can view the relevant information by executing the above example , Because of the file no-such-user.json non-existent .

It's a little bad , Because mistakes just fall on the chain , No details : What failed , Where did you fail .

So let's add one more step : We should check for HTTP State of response.status attribute , If not 200 Just throw the error .

class HttpError extends Error { // (1)
  constructor(response) {
    super(`${response.status} for ${response.url}`);
    this.name = 'HttpError';
    this.response = response;
  }
}

function loadJson(url) { // (2)
  return fetch(url)
    .then(response => {
      if (response.status == 200) {
        return response.json();
      } else {
        throw new HttpError(response);
      }
    })
}

loadJson('no-such-user.json') // (3)
  .catch(alert); // HttpError: 404 for .../no-such-user.json
 Copy code 
  1. We are HTTP Error creating a custom class to distinguish HTTP Errors and other types of errors . Besides , The new class has a constructor, It accepts response object , And save it to error in . therefore , Error handling (error-handling) The code can get the response data .
  2. Then we will ask (requesting) And error handling code wrapped into a function , It can fetch url and All status codes are not 200 Treat as a mistake . This is very convenient , Because we usually need such logic .
  3. Now? alert Show more useful descriptions .

The advantage of having our own error handling class is that we can use instanceof It's easy to check for errors in error handling code .

for example , We can create requests , If we get 404 You can tell the user to modify the information .

The following code is from GitHub Load the user with the given name . Without this user , It will tell the user to fill in the correct name :

function demoGithubUser() {
  let name = prompt("Enter a name?", "iliakan");

  return loadJson(`https://api.github.com/users/${name}`)
    .then(user => {
      alert(`Full name: ${user.name}.`);
      return user;
    })
    .catch(err => {
      if (err instanceof HttpError && err.response.status == 404) {
        alert("No such user, please reenter.");
        return demoGithubUser();
      } else {
        throw err; // (*)
      }
    });
}

demoGithubUser();
 Copy code 

Please note that : there .catch Will catch all errors , But it just “ Know how to deal with ” HttpError 404. In that special case , It means that there are no such users , and .catch Try again only in this case .

For other errors , It doesn't know what will happen . It may be a programming error or other error . So it's just (*) Line throws again .

other

If we have loading instructions (load-indication),.finally Is a good handler (handler), stay fetch Stop it when finished :

function demoGithubUser() {
  let name = prompt("Enter a name?", "iliakan");

  document.body.style.opacity = 0.3; // (1)  Start instruction (indication)

  return loadJson(`https://api.github.com/users/${name}`)
    .finally(() => { // (2)  Stop indication (indication)
      document.body.style.opacity = '';
      return new Promise(resolve => setTimeout(resolve)); // (*)
    })
    .then(user => {
      alert(`Full name: ${user.name}.`);
      return user;
    })
    .catch(err => {
      if (err instanceof HttpError && err.response.status == 404) {
        alert("No such user, please reenter.");
        return demoGithubUser();
      } else {
        throw err;
      }
    });
}

demoGithubUser();
 Copy code 

Here (1) That's ok , We indicate loading by dimming the document . There is no problem with the indication method , Any type of indication can be used instead of .

When promise To be solved ,fetch It can be success or error ,finally stay (2) Line triggers and terminates the load instruction .

There is a browser trick ,(*) It's from finally Return to zero delay (zero-timeout) Of promise. This is because some browsers ( such as Chrome) need “ A little time ” External promise Handler to draw changes to the document . So it ensures that before entering the next step in the chain , The indication is visually stopped .

48. Promise API

Promise Like 5 A static method :

  1. Promise.all(promises) —— Wait for all promise all resolve when , Returns an array of their results . If any given promise by reject, Then it becomes Promise.all Of error, All the others promise The results will be ignored .

  2. Promise.allSettled(promises)(ES2020 The new method )—— Wait for all promise all settle when , And return their results as an array of objects containing the following :

    • status: "fulfilled" or "rejected"
    • value( If fulfilled) or reason( If rejected).
  3. Promise.race(promises) —— Waiting for the first settle Of promise, And its result/error As a result .

  4. Promise.resolve(value) —— Use given value Create a resolved Of promise.

  5. Promise.reject(error) —— Use given error Create a rejected Of promise.

Of the five methods ,Promise.all Probably the most used in actual combat .

49. Micro task (Microtask)

Promise Processing is always asynchronous , Because all promise Behavior will pass through internal “promise jobs” queue , Also known as “ Micro task queue ”(ES8 The term ).

therefore ,.then/catch/finally The handler (handler) It is always called after the current code is complete .

If we need to make sure that a piece of code is in .then/catch/finally Then it's executed , We can add it to the chain call .then in .

In most JavaScript In the engine ( Including browsers and Node.js), Micro task (microtask) The concept of “ The event loop (event loop)” and “ Macro task (macrotasks)” Closely related .

50. Async/await

Keyword before function async It does two things :

  1. Let this function always return a promise.
  2. Allow to use... Within this function await.

Promise Keywords before await send JavaScript The engine waits for the promise settle, then :

  1. If there is error, Will throw an exception — It's like there called throw error equally .
  2. otherwise , Just return the result .

These two keywords together provide a good framework for writing asynchronous code , This code is easy to read and easy to write .

With async/await after , We hardly need to use promise.then/catch, But don't forget that they are based on promise Of , Because sometimes ( For example, in the outermost scope ) We have to use these methods . also , When we need to wait for tasks at the same time ,Promise.all It's very easy to use .

51. Generator

  • Generator It's through generator function function* f(…) {…} Created .
  • stay generator( Only in ) Inside , There is yield operation .
  • External code and generator May pass next/yield Call exchange result .

In modern times JavaScript in ,generator Rarely used . But sometimes they come in handy , Because the ability of a function to exchange data with the calling code during execution is very unique . and , Of course , They are ideal for creating iteratable objects .

also , In the next chapter we will learn async generator, They are used in for await ... of Read the asynchronously generated data stream in the loop ( for example , Extract through network paging (paginated fetches over a network)).

stay Web Programming , We often use data streams , So this is another very important usage scenario .

52. Asynchronous iteration and generator

The conventional iterator and generator It can handle data that doesn't take time to generate .

When we expect to asynchronously , When acquiring data with delay , You can use their asynchronous versions , And use for await..of replace for..of.

asynchronous iterator And Convention iterator Grammatical differences :

asynchronous generator And Convention generator Grammatical differences :

stay Web In development , We often encounter data flow , They flow in segments (flows chunk-by-chunk). for example , Download or upload large files .

We can use asynchronous generator To process such data . It is worth noting that , In some environments , For example, in browser environment , There is another one called Streams Of API, It provides a special interface to handle such data streams , Transform data and transfer data from one data stream to another ( for example , Download from one place and immediately send to other places ).

53. modular (Module) brief introduction

Let's summarize the core concepts of the module :

  1. A module is a file . The browser needs to use
  • The default is deferred resolution (deferred).
  • Async Can be used for inline scripts .
  • From another source ( Domain / agreement / port ) Loading external scripts , need CORS header.
  • Duplicate external scripts are ignored
  1. The module has its own local top-level scope , And can pass through import/export Switching function .
  2. Modules always use use strict.
  3. The module code is executed only once . The export is created only once , Then it will be shared between imports .

When we use modules , Each module implements specific functions and exports them . And then we use import Just import it directly to where you need it . The browser will automatically load and parse the script .

In the production environment , For performance and other reasons , Developers often use tools such as Webpack Packaging tools like package modules together .

54. Export and import

  • In a statement class/function/… Before :

    • export [default] class/function/variable ...
  • Independent export :

    • export {x [as y], ...}.
  • Re export :

    • export {x [as y], ...} from "module"
    • export * from "module"( The default export... Will not be re exported ).
    • export {default [as y]} from "module"( Re export the default export ).

Import :

  • Named exports in the module :

    • import {x [as y], ...} from "module"
  • Default export :

    • import x from "module"
    • import {default as x} from "module"
  • all :

    • import * as obj from "module"
  • The import module ( Its code , And run ), But don't assign it to a variable :

    • import "module"

We put import/export Statement at the top or bottom of the script , It doesn't matter .

therefore , Technically speaking , There is no problem with the following code :

sayHi();

// ...

import {sayHi} from './say.js'; //  Import... At the bottom of the file 
 Copy code 

In actual development , The import is usually at the beginning of the file , But it's just for convenience .

Please note that {...} Medium import/export Invalid statement .

A conditional import like this is invalid :

if (something) {
  import {sayHi} from "./say.js"; // Error: import must be at top level
}
 Copy code 

55. Proxy and Reflect

Proxy Is the wrapper of the object , Forward operations on the agent to the object , And you can choose to capture some of these operations .

It can wrap any type of object , Including classes and functions .

The grammar is :

let proxy = new Proxy(target, {
  /* trap */
});
 Copy code 

…… then , We should use it everywhere proxy instead of target. The agent does not have its own properties or methods . If a catcher is provided (trap), It will capture the operation , Otherwise, it will be forwarded to target object .

We can capture :

  • Read (get), write in (set), Delete (deleteProperty) attribute ( Even nonexistent properties ).
  • Function call (apply Catcher ).
  • new operation (construct Catcher ).
  • Many other operations ( For a complete list, see the beginning of this article and docs).

This enables us to create “ fictitious ” Properties and methods , Implement default values , Observable object , Function decorators, etc .

We can also wrap objects in different proxies multiple times , And decorate it with various functions .

Reflect API It aims to supplement Proxy. For any Proxy Catcher , All have a... With the same parameters Reflect call . We should use them to forward the call to the target object .

Proxy There are some limitations :

  • Built in objects have “ Internal slot ”, Access to these objects cannot be proxied . Refer to the solution above .
  • The same is true for private class fields , Because they are also implemented internally using slots . therefore , The invocation of a proxy method must have a target object as this To access them .
  • Strict equality checking of objects === Can't be intercepted .
  • performance : The benchmark (benchmark) Depends on engine , But it usually takes several times longer to access properties using the simplest proxy . actually , This is only for some “ bottleneck ” It's important for the object .

56. Traverse DOM

Given a DOM node , We can use navigation (navigation) Property to access its immediate neighbors .

These attributes are mainly divided into two groups :

  • For all nodes :parentNode,childNodes,firstChild,lastChild,previousSibling,nextSibling.
  • For element nodes only :parentElement,children,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling.

Some types of DOM Elements , for example table, Provides additional properties and collections for accessing its content .

57. Search for :getElement*,querySelector*

Yes 6 There are two main ways , Can be in DOM Search for prime nodes :

Besides : So far, , The most common is querySelector and querySelectorAll, however getElement(s)By* It may be useful occasionally , Or you can find it in the old script .

  • elem.matches(css) Used for inspection elem And given CSS Whether the selectors match .
  • elem.closest(css) Used to find a connection with a given CSS The selector matches the nearest ancestor .elem Itself will also be checked .

Let's mention another way to check the relationship between children and parents , Because it's sometimes useful :

  • If elemB stay elemA Inside (elemA The offspring of ) perhaps elemA==elemB,elemA.contains(elemB) Will return true.

58. Node properties :type,tag and content

Every DOM Nodes belong to a specific class . These classes form a hierarchy (hierarchy). The complete set of properties and methods is the result of inheritance .

The main DOM Node attributes are :

nodeType We can use it to see whether the node is a text node or an element node . It has a numeric value (numeric value):1 Show elements ,3 Represents a text node , Others represent other node types . read-only .

nodeName/tagName Used for element names , Tag name ( except XML Pattern , All in capitals ). For non element nodes ,nodeName Describes what it is . read-only .

innerHTML Elemental HTML Content . Can be modified .

outerHTML The integrity of the elements HTML. Yes elem.outerHTML The write operation will not touch elem In itself . Instead, replace it with a new... In the external context HTML.

nodeValue/data Non element nodes ( Text 、 notes ) The content of . They are almost the same , We usually use data. Can be modified .

textContent The text within the element :HTML Subtract all . Writing text puts the text inside the element , All special characters and labels are considered text . You can safely insert user generated text , And prevent unnecessary HTML Insert .

hidden When set to true when , Execution and CSS display:none The same thing .

DOM Nodes also have other properties , The specific attributes depend on their classes . for example , Elements (HTMLInputElement) Support value,type, and Elements (HTMLAnchorElement) It supports href etc. . Most standards HTML characteristic (attribute) Have corresponding DOM attribute .

59. Features and attributes (Attributes and properties)

- characteristic (attribute)— Written in HTML The content in .- attribute (property)— DOM Content in object .

A brief comparison :

elem.hasAttribute(name) — Check if this feature exists . Method of operating characteristics :

- elem.getAttribute(name) — Get the value of this property .- elem.setAttribute(name, value) — Set this property value .- elem.removeAttribute(name) — Remove this feature .- elem.attributes — A collection of all features .

in the majority of cases , Best use DOM attribute . Only when the DOM Properties cannot meet development needs , And when we really need features , To use features , for example :

- We need a non-standard feature . But if it takes data- start , Then we should use dataset.- We want to read HTML in “ Written ” value . Corresponding DOM Properties may be different , for example href Property has always been a complete URL, But what we want is “ The original ” value .

60. Modify the document (document)

[- How to create a new node :

-   document.createElement(tag) —  Create an element node with the given label ,
-   document.createTextNode(value) —  Create a text node ( Rarely used ),
-   elem.cloneNode(deep) —  Clone elements , If  deep==true  Then clone it with its offspring .-    Methods of inserting and removing nodes :

-   node.append(...nodes or strings) —  stay  node  Insert at end ,
-   node.prepend(...nodes or strings) —  stay  node  Insert... At the beginning ,
-   node.before(...nodes or strings) —  stay  node  Insert before ,
-   node.after(...nodes or strings) —  stay  node  Then insert ,
-   node.replaceWith(...nodes or strings) —  Replace  node.
-   node.remove() —  remove  node.](https://link.juejin.cn?target=undefined)
 Copy code 

The text string is “ As text ” Insert .

[- There are also “ old type ” Methods :

-   parent.appendChild(node)
-   parent.insertBefore(node, nextSibling)
-   parent.removeChild(node)
-   parent.replaceChild(newElem, node)](https://link.juejin.cn?target=undefined)
 Copy code 

These methods all return node.

[- stay html Given some HTML,elem.insertAdjacentHTML(where, html) Will be based on where To insert it :

-   "beforebegin" —  take  html  Insert into  elem  front ,
-   "afterbegin" —  take  html  Insert into  elem  The beginning of ,
-   "beforeend" —  take  html  Insert into  elem  At the end of ,
-   "afterend" —  take  html  Insert into  elem  Back .](https://link.juejin.cn?target=undefined)
 Copy code 

in addition , There's a similar way ,elem.insertAdjacentText and elem.insertAdjacentElement, They insert text strings and elements , But rarely used .

[- Before the page is loaded HTML Attach to page :

-   document.write(html)](https://link.juejin.cn?target=undefined)
 Copy code 

After the page loads , Such a call will erase the document . More common in old scripts .

61. Styles and classes

To manage class, There are two DOM attribute :

- className — A string value , You can well manage the entire collection of classes .- classList — have add/remove/toggle/contains Object of method , It can well support a single class .

To change the style :

To read the parsed (resolved) style ( For all classes , Apply all CSS And calculate the final value ):

  • getComputedStyle(elem, [pseudo]) Return and style Objects similar to , And contains objects of all classes . read-only .

62. Element size and scrolling

The element has the following geometric attributes :

  • offsetParent — It's the closest CSS Locate your ancestors , Or is it td,th,table,body.
  • offsetLeft/offsetTop — Is relative to offsetParent Coordinates of the upper left corner edge of .
  • offsetWidth/offsetHeight — Elemental “ external ” width/height, Frame (border) Dimensions are included .
  • clientLeft/clientTop — The distance from the outer corner of the upper left corner of the element to the inner corner of the upper left corner . For operating systems that display content from left to right , They are always on the left / Top border Width . For an operating system that displays content from right to left , The vertical scroll bar is on the left , therefore clientLeft It also includes the width of the scroll bar .
  • clientWidth/clientHeight — Content width/height, Include padding, But it doesn't include the scroll bar (scrollbar).
  • scrollWidth/scrollHeight — Content width/height, It's like clientWidth/clientHeight equally , But it also includes the invisible part of the element that scrolls out .
  • scrollLeft/scrollTop — Start from the upper left corner of the element , Scroll out the top half of the element width/height.

except scrollLeft/scrollTop Outside , All properties are read-only . If we modify scrollLeft/scrollTop, The browser will scroll through the corresponding elements .

63. Window Size and scrolling

The geometric :

  • Of the visible part of the document width/height( Content area width/height):document.documentElement.clientWidth/clientHeight

  • Of the entire document width/height, This includes the rolling out part :

    let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight );

rolling :

  • Read the current scroll :window.pageYOffset/pageXOffset.

  • Change the current scroll :

    • window.scrollTo(pageX,pageY) — Absolute coordinates ,
    • window.scrollBy(x,y) — Scroll relative to the current position ,
    • elem.scrollIntoView(top) — Scroll to make elem so (elem With the top of the window / Align Bottom ).

64. Introduction to browser Events

Here you are 3 A way to allocate event handlers :

  1. HTML characteristic (attribute):onclick="...".
  2. DOM attribute (property):elem.onclick = function.
  3. Method (method):elem.addEventListener(event, handler[, phase]) Used to add ,removeEventListener For removal .

HTML Features are rarely used , because HTML In the tag JavaScript It looks strange and strange . And you can't write too much code in it .

DOM Properties can also be used , But we can't assign multiple handlers to a particular event . In many scenarios , This restriction is not serious .

The last way is the most flexible , But it's also the longest to write . There are a few events that can only be used in this way . for example transtionend and DOMContentLoaded( As mentioned above ).addEventListener Objects are also supported as event handlers . under these circumstances , If something happens , It will call handleEvent Method .

No matter how you classify the handler —— It will get an event object as the first parameter . This object contains details about what happened .

65. Bubbling and trapping

When an event happens —— The deepest nested element where this event occurs is marked as “ Target element ”(event.target).

  • then , The event moves down from the document root node to event.target, And called the assignment on the way addEventListener(..., true) Processing program (true yes {capture: true} An abbreviated form of ).
  • then , Call the handler on the target element itself .
  • then , Events from event.target Bubbling to the root , Call to use on、HTML characteristic (attribute) And without the third parameter , Or the third parameter is false/{capture:false} Of addEventListener Assigned handler .

Every handler can access event Object properties :

  • event.target —— The deepest element of the hierarchy that caused the event .
  • event.currentTarget(=this)—— Handle the current element of the event ( Element with handler )
  • event.eventPhase —— At this stage (capturing=1,target=2,bubbling=3).

Any event handler can call event.stopPropagation() To stop the event , But this is not recommended , Because we're not sure if we really don't need bubbling Events , Maybe it's for something completely different .

The capture phase rarely uses , Usually we deal with events when bubbling . There is a logic behind this .

In the real world , When the accident happened , The local police will respond first . They know best where this happened . then , if necessary , The superior competent department shall deal with it again .

The same is true of event handlers . Code that sets the handler on a specific element , Learn the most detailed information about this element . Specific to Your handler may be just right for this , This handler knows all the information about the element . So the handler should get the chance first . then , Its immediate parent element also knows the context , But I know less , And so on , Until you deal with general concepts and run the topmost element of the last handler .

66. Event delegation

It is often used to add the same processing to many similar elements , But not limited to .

Algorithm :

  1. In the container (container) Put a handler on .
  2. In the handler —— Check the source element event.target.
  3. If the event occurs within the element we are interested in , Then deal with the event .

benefits :

  • Simplify initialization and save memory : There is no need to add many handlers .
  • Less code : When adding or removing elements , No need to add / Remove handler .
  • DOM modify : We can use innerHTML etc. , To batch add / Remove elements .

Event delegation also has its limitations :

  • First , Events must bubble . And some events don't bubble . Besides , Low level handlers should not use event.stopPropagation().
  • secondly , Delegation may increase CPU load , Because container level handlers respond to events anywhere in the container , Whether we are interested in the event or not . however , Usually the load is negligible , So we don't think about it .

67. Browser default behavior

There are many default browser behaviors :

  • mousedown —— Start choosing ( Move the mouse to select ).
  • stay Upper click —— Choose / Unselected input.
  • submit —— Click on Or press... In the form field Enter The key triggers this event , The browser will then submit the form .
  • keydown —— Pressing a key causes characters to be added to the field , Or trigger other actions .
  • contextmenu —— The event occurs when the right mouse button is clicked , The triggered behavior is to display the browser context menu .
  • …… There are more ……

If we just want to pass JavaScript To deal with Events , Then all default behaviors can be blocked .

Want to block default behavior —— have access to event.preventDefault() or return false. The second method is only applicable through on Assigned handler .

addEventListener Of passive: true Option tells the browser that the behavior will not be blocked . For some mobile Events ( image touchstart and touchmove) It is useful to , Used to tell the browser that it should not wait for all handlers to complete before scrolling .

If the default behavior is blocked ,event.defaultPrevented The value of will become true, Otherwise false.

68. Create custom events

To generate an event from the code , We first need to create an event object .

General purpose Event(name, options) The constructor accepts arbitrary event names and events with two properties options object :

  • If the event should bubble , be bubbles: true.
  • If event.preventDefault() Should be effective , be cancelable: true.

Other images MouseEvent and KeyboardEvent The constructor of such a native event , All accept properties specific to the event type . for example , Mouse events clientX.

For custom events , We should use CustomEvent Constructors . It has a name called detail Additional options for , We should assign event specific data to it . then , All handlers can be in event.detail To access it .

Although it is technically possible to generate images like click or keydown Such browser Events , But we should use them with caution .

We should not generate browser Events , Because it's a weird way to run a handler (hacky) The way . Most of the time , It's all bad architecture .

Can generate native Events :

  • If the third equation library does not provide other interaction modes , So this is a dirty means to make the third equation library work .
  • For automated testing , In the script “ Click button ” And check whether the interface responds correctly .

Custom events with our own names are usually created for architectural purposes , To indicate what happens in the menu (menu), slider (slider), Wheel planting (carousel) Wait for what happens inside .

69. Mouse events

Mouse events have the following properties :

  • Button :button.

  • Composite key ( If pressed, it is true):altKey,ctrlKey,shiftKey and metaKey(Mac).

    • If you want to deal with Ctrl, Then don't forget Mac user , They usually use Cmd, So it's best to check if (e.metaKey || e.ctrlKey).
  • Window relative coordinates :clientX/clientY.

  • Document relative coordinates :pageX/pageY.

mousedown The default browser action is text selection , If it's bad for the interface , It should be avoided .

70. Move the mouse :mouseover/out,mouseenter/leave

Note the following :

  • Moving the mouse quickly may skip intermediate elements .
  • mouseover/out and mouseenter/leave Event also has an additional attribute :relatedTarget. This is where we come from / To the element , It's right target A supplement to .

Even when we go from parent to child , It will also trigger mouseover/out event . The browser assumes that the mouse will only be on one element at a time —— The deepest one .

mouseenter/leave Events are different in this regard : They trigger only when the mouse enters and leaves the element . And they don't bubble .

71. event :change,input,cut,copy,paste

Data change event :

Reprint :juejin.cn/post/698545…

copyright notice
author[Beginner's self],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827082111716V.html

Random recommended