Free learning recommendation: javascript learning tutorial
##1. What is JavaScript
1-1. JavaScript implementation
Although JavaScript and ECMAScript are basically synonyms, JavaScript is far from limited to ECMA- 262 as defined. The complete JavaScript implementation contains: At a basic level, describes the language: syntax, types, statements, keywords, reserved words, operators, global objects
. JavaScript implements ECMAScript, and Adobe ActionScript also implements
ECMAScript.
1-2, DOM
The Document Object Model (DOM, Document Object Model) is an application programming interface (API) for using extensions in HTML XML. DOM abstracts the entire page into a set of hierarchical nodes. Each component of an HTML or XML page is a node that contains different data.
DOM allows developers to control the content and structure of web pages as they wish by creating a tree that represents the document. Using the DOM API, nodes can be easily deleted, added, replaced, and modified.
IE3 and Netscape Navigator 3 provide
Browser Object Model(BOM) API to support access and Manipulate the browser window. Using the BOM, developers can control parts of the page other than what the browser displays. The truly unique thing about BOM, and certainly the most problematic, is that it is the only JavaScript implementation without relevant standards. HTML5 changes this situation. This version of HTML covers as many BOM features as possible in the form of formal specifications. Due to the emergence of HTML5, many previous problems related to BOM have been solved. In general, BOM mainly targets browser windows and sub-windows (frames), but
people usually put any browser-specific extensions within the scope of BOM. The following are some such extensions:2-1, script
ElementThe primary way to insert JavaScript into HTML is to use the script element. This
element was created by Netscape and was first implemented in Netscape Navigator 2. Later, this element was officially added to the HTML specification. The script element has eight attributes listed below.
async
charset: Optional. Use the code character set specified by the src attribute. This attribute is rarely used because most browsers don't care about its value.
that outbound requests will include credentials.
defer: Optional. It means that there is no problem in executing the script after the document parsing and display is completed. Only valid for external script files. In IE7 and earlier, this attribute can also be specified for inline scripts.
src: Optional. Represents an external file containing code to be executed.
type : Optional. In place of language , represents the content type (also called a MIME type) of the scripting language in the code block.
The code contained in the script will be interpreted from top to bottom
2-2,
uses src The script element of the attribute should no longer contain other JavaScript code within the script and /script tags. If both are provided, the browser will simply download and execute the script file, ignoring inline code. One of the most powerful and controversial features of the
script element is that it can contain JavaScript files from external domains. Much like the img element, the src attribute of the script element can be a complete URL, and the resource pointed to by this URL can not be in the same domain as the HTML page containing it
2-3. Documentation Mode
You can use doctype to switch the document mode. There are two initial document modes: Mixed mode (quirks mode) and Standard mode (standards mode). The former makes IE like IE5 (supporting some non-standard features), and the latter makes IE have standards-compliant behavior. Although the main difference between the two modes is only in the content rendered through CSS, there are also some related effects, or side effects, on JavaScript. These side effects will be mentioned frequently in this book.
After IE first supported document mode switching, other browsers also followed suit. With the widespread implementation of browsers, a third document mode has emerged: quasi-standards mode (almost
standards mode). Browsers in this mode support many standard features, but are not as strict as the standards. The main difference is how the white space around image elements is treated (most noticeable when using images in tables).
Mixed mode is switched in all browsers by omitting the doctype declaration at the beginning of the document. This agreement is unreasonable, because the mixed mode is very different in different browsers, and there is basically no browser consistency without using black technology.
2-4. noscript element
In view of the problem that early browsers do not support JavaScript, a solution for graceful page degradation is needed. Eventually, the element emerged and was used to provide alternative content to browsers that did not support JavaScript. Although today’s browsers already support 100% JavaScript, this element still has its uses for browsers that disable JavaScript. The
element can contain any HTML element that can appear in,
3. Grammar Basics
3-1. Grammar
The first thing to know is that everything in ECMAScript is size-sensitive Write. Whether it is a variable, function name or operator, they are case-sensitive. In other words, the variable test and the variable Test are two different variables. Similarly, typeof cannot be used as a function name because it is a keyword (more on this later). But Typeof is a perfectly valid function name.
3-2. Identifier
The so-called identifier is the name of a variable, function, attribute or function parameter. An identifier can consist of one or more of the following characters:
The letters in the identifier can be letters in Extended ASCII (Extended ASCII), or Unicode alphabetic characters, such as À and Æ (but this is not recommended).
By convention, ECMAScript identifiers use camel case, that is, the first letter of the first word is lowercase, and the first letter of each subsequent word is capitalized
3-3. Strict Mode
ECMAScript 5 adds the concept of strict mode. Strict mode is a different JavaScript parsing and execution model. Some non-standard writing methods of ECMAScript 3 will be processed in this mode, and errors will be thrown for unsafe activities
3-4 , Keywords and reserved words
ECMA-262 describes a set of reserved keywords, which have special uses, such as indicating the beginning and end of a control statement, or performing specific operations
All keywords specified in ECMA-262 6th Edition:
break do in typeof case else instanceof var catch export new void class extends return while const finally super with continue for switch yield debugger function this default if throw delete import try
A set of future reserved words are also described in the specification and likewise cannot be used as identifiers or attribute names . Although reserved words have no specific purpose in the language, they are reserved for future keyword use
3-5. Variables
ECMAScript variables are loosely typed , meaning that variables can be used to hold any type of data. Each variable is nothing more than a named placeholder used to hold an arbitrary value. There are 3 keywords to declare variables: var, const and let. Among them, var can be used in all versions of CMAScript, while const and let can only be used in ECMAScript 6 and later versions
3-6, var keyword
var declaration scope
The key problem is that a variable defined using the var operator will become a local variable of the function that contains it. For example, using var to define a variable inside a function means that the variable will be destroyed when the function exits
var declaration promotion
When using var, the following code does not An error will be reported. This is because variables declared using this keyword will automatically be promoted to the top of the function scope
3-7. let declaration
let followed by var does the same thing, but with a very important difference. The most obvious difference is that the scope of let declarations is block scope, while the scope of var declarations is function scope.
Temporary Dead Zone
Another important difference between let and var is that variables declared by let will not be promoted in the scope.
Global declaration
Unlike the var keyword, variables declared in the global scope using let will not become attributes of the window object (variables declared with var will)
Conditional declaration
When using var to declare a variable, since the declaration will be promoted, the JavaScript engine will automatically merge the redundant declarations into one declaration at the top of the scope. Because the scope of let is a block, it is impossible to check whether a variable with the same name has been previously declared using let, and it is also impossible to declare it without a declaration
in a for loop Let declaration
Before let appears, the iteration variable defined by the for loop will penetrate outside the loop body
const declaration
The behavior of const is basically the same as let, the only one The important difference is that when you declare a variable with it, you must also initialize the variable, and trying to modify a variable declared with const will result in a runtime error.
3-8. Declarative style and best practices
ECMAScript 6 adds let and const to objectively make this language more precise Declaration scope and semantics provide better support. The JavaScript community has been troubled by various problems caused by weirdly behaving vars for many years. With the emergence of these two new keywords, new best practices that help improve code quality are gradually emerging.
4. Data types
ECMAScript has 6 simple data types (also called primitive types): Undefined, Null, Boolean, Number, String and Symbol. Symbol (symbol) is new in ECMAScript 6. There is also a complex data type called Object. Object is an unordered collection of name-value pairs. Because you cannot define your own data types in ECMAScript, all values can be represented by one of the seven data types mentioned above. Only 7 data types don't seem to be enough to represent all the data. However, the data types of ECMAScript are very flexible. One data type can be used as multiple data types
4-1. Typeof operator
Because of the types of ECMAScript The system is loose, so a means is needed to determine the data type of any variable. This is where the typeof operator comes in. Using the typeof operator on a value will return one of the following strings:
"undefined" means the value is undefined;
"boolean" means the value is a Boolean value;
"string" means the value is a string;
"number" means the value is a numeric value;
"object" means the value is an object (not a function) or null;
"function" means the value is a function;
"symbol" means the value is a symbol .
4-2. Undefined type
The Undefined type has only one value, which is the special value undefined. When a variable is declared using var or let but not initialized, it is equivalent to assigning an undefined value to the variable.
Even though uninitialized variables will automatically be assigned an undefined value, we still recommend that you declare the variable at the same time. initialization. This way, when typeof returns "undefined", you know it's because the given variable hasn't been declared yet, rather than because it was declared but uninitialized.
4-3. Null type
The Null type also has only one value, which is the special value null. Logically speaking, the null value represents a null object pointer, which is why passing null to typeof will return "object"
When defining variables that will store object values in the future, it is recommended to use null to initialize them. Use other values. In this way, just by checking whether the value of this variable is null, you can know whether this variable is later reassigned a reference to an object
Using the equal operator (==) to compare null and undefined always returns true. But be aware that this operator converts its operands for comparison.
Even though null and undefined are related, their uses are completely different. As mentioned before, you never have to explicitly set a variable value to undefined . But null is not like that. Any time a variable holds an object and there is no such object to hold, the variable must be filled with null. This preserves the semantics that null is a pointer to a null object and further distinguishes it from undefined.
null is a false value. So it can be detected in a more concise way if needed. Keep in mind, though, that there are many other possible values that are also false. So you must make it clear that what you want to detect is the literal value of null, not just the false value
4-4, Boolean type
Boolean (Boolean value) type It is one of the most frequently used types in ECMAScript and has two literal values: true and false. These two Boolean values are different from numeric values, so true is not equal to 1 and false is not equal to 0
Note: The Boolean literals true and false are case-sensitive, so True and False (and other mixed cases form) is a valid identifier, but not a Boolean value.
4-5. Number type
Perhaps the most interesting data type in ECMAScript is Number. The Number type represents integers and floating-point values (also called double-precision values in some languages) using the IEEE 754 format. Different numerical types have different numerical literal formats accordingly
Floating point value
To define a floating point value, the value must contain a decimal point, and the decimal point must be followed by
There is one missing number. Although it is not necessary to have an integer before the decimal point, it is recommended.
Range of values
Due to memory limitations, ECMAScript does not support representing all values in the world. The minimum value that ECMAScript can represent is stored in Number.MIN_VALUE. This value is 5e-324 in most browsers. The maximum value that can be represented is stored in Number.MAX_VALUE. This value is 1.797 693 134 862 315 in most browsers. 7e 308. If the numerical result of a calculation exceeds the range that JavaScript can represent, the value will be automatically converted to a special Infinity value. Any unrepresentable negative number is represented by -Infinity (negative infinity), and any unrepresentable positive number is represented by Infinity (positive infinity). If a calculation returns a positive Infinity or a negative Infinity , the value cannot be used further in any calculation. This is because Infinity has no numeric representation that can be used for calculations. To determine whether a value is finite (that is, between the minimum and maximum values that JavaScript can represent), you can use the isFinite() function
NaN
There is a special The value is called NaN, which means "Not a Number" and is used to indicate that the operation that was supposed to return a value failed (instead of throwing an error). For example, dividing any number by zero usually results in an error in other languages, aborting code execution. But in ECMAScript, division by 0, 0 or -0 will return NaN
Numeric conversion
There are 3 functions that can convert non-numeric values into numeric values: Number(), parseInt () and parseFloat(). Number() is a conversion function that can be used for any data type. The latter two functions are mainly used to convert strings into numerical values. For the same parameters, these three functions perform different operations.
4-6, NaN
There is a special value called NaN, which means "Not aNumber" (Not aNumber), used for Indicates that the operation that was supposed to return a value failed (rather than throwing an error).
4-7. Numeric conversion
There are three functions that can convert non-numeric values into numeric values: Number(), parseInt() and parseFloat(). Number() is a conversion function that can be used for any data type. The latter two functions are mainly used to convert strings into numerical values. For the same parameters, these three functions perform different operations. The Number() function performs conversion based on the following rules. Boolean value, true converts to 1, false converts to 0.
Numeric value, returned directly. null , returns 0. undefined , returns NaN .
4-8. String type
String (string) data type represents zero or more 16-bit Unicode character sequences. Strings can be marked with double quotes ("), single quotes (') or backticks (`),
Character literals
The string data type contains some character literals , used to represent non-printing characters or characters with other uses
Characteristics of strings
Strings in ECMAScript are immutable, which means that once created, Their values cannot be changed. To modify the string value in a variable, you must first destroy the original string and then save another string containing the new value to the variable
Convert to string
There are two ways to convert a value to a string. The first is to use the toString() method that almost all values have. The only purpose of this method is to return the string equivalent of the current value
Template literals
ECMAScript 6 adds the ability to use template literals to define strings. Unlike using single or double quotes, template literals retain newline characters and can define strings across lines
String interpolation
One of the most commonly used features of template literals is to support characters String interpolation means that one or more values can be inserted into a continuous definition. Technically speaking, a template literal is not a string, but a special JavaScript syntax expression, but the result after evaluation is a string. Template literals are immediately evaluated and converted to string instances when they are defined, and any inserted variables will also take their values from their closest scope
Template literal label function
Template literals also support defining tag functions, and the interpolation behavior can be customized through tag functions. The label function receives the template separated by interpolation tokens and the result of evaluating each expression. The tag function itself is a regular function that applies custom behavior by prefixing it to the template literal.
Original string
You can also directly obtain the original template literal using the template literal content (such as newline characters or Unicode characters), rather than the converted character representation. For this purpose, you can use the default String.raw tag function
5. Operators
ECMA-262 describes a set of operations that can be used Operators for data values, including mathematical operators (such as addition, subtraction), bitwise operators, relational operators, equality operators, etc. Operators in ECMAScript are unique in that they can be used on a variety of values, including strings, numbers, Boolean values, and even objects. When applied to an object, operators typically call the valueOf() and/or toString() methods to obtain a computable value. 3.5.1 Unary operator An operator that only operates on one value is called a unary operator. The unary operator is the simplest operator in ECMAScript.
5-1. Unary operators
2. Unary addition and subtraction
The unary addition and subtraction operators are suitable for most They are not new to developers; they are used in ECMAScript as they are in high school math. Unary addition is represented by a plus sign ( ), which is placed in front of the variable and has no effect on the value.
5-2. Bit operators
Bitwise NOT
The bitwise NOT operator is represented by the tilde symbol (~), and its function is to return the one's complement of the value. Bitwise NOT is one of the few binary mathematical operators in ECMAScript
Bitwise AND
The bitwise AND operator is represented by the ampersand (&), there are Two operands. Essentially, bitwise AND is to align each bit of two numbers, and then perform the corresponding AND operation on each bit based on the rules in the truth table.
Bitwise OR
The bitwise OR operator is represented by the pipe symbol (|) and also has two operands.
Bitwise XOR
Bitwise XOR is represented by the caret (^), and there are also two operands
left Shift
The left shift operator is represented by two less than signs ( << ), which will move all bits of the value to the left according to the specified number of digits. For example, if the value 2 (binary 10) is shifted 5 bits to the left, you will get 64 (binary 1000000)
Signed right shift
Signed right shift consists of two greater than The sign ( >> ) means that all 32 bits of the value will be shifted to the right while preserving the sign (positive or negative). Signed right shift is actually the inverse operation of left shift
Unsigned right shift
Unsigned right shift is represented by 3 greater than signs (>>>), Will shift all 32 bits of the value to the right. For positive numbers, unsigned right shift has the same result as signed right shift
5-3, Boolean operator
Logical NOT
The logical NOT operator is represented by an exclamation mark (!) and can be applied to any value in ECMAScript. This operator always returns a Boolean value, regardless of the data type it is applied to. The logical NOT operator first converts the operand to a Boolean value and then inverts it
Logical AND
The logical AND operator is represented by two ampersands (&&), Applied to two values
Logical OR
The logical OR operator is represented by two pipe characters (||)
# #5-4. Multiplicative operator
The multiplication operator is represented by an asterisk (*) and can be used to calculate the value of two values. product.
The division operator is represented by a slash (/) and is used to calculate the quotient of dividing the first operand by the second operand
6. Statements
ECMA-262 describes some statements (also called flow control statements), and most of the syntax in ECMAScript is reflected in in the statement. Statements usually use one or more keywords to accomplish a given task. Statements can be simple or complex. It can be as simple as telling the function to exit, or as complex as listing a bunch of instructions to be executed repeatedly.
6-1. do-while statement
The do-while statement is a post-test loop statement, that is, after the code in the loop body is executed
Only then will the exit condition be evaluated. In other words, the code in the loop body is executed at least once Detect the exit condition and then execute the code inside the loop. Therefore, the code in the while loop body may not be executed.
7. Functions
Functions are core components of any language because they can encapsulate statements. Then execute it anywhere, anytime. Functions in ECMAScript are declared using the function keyword, followed by a set of parameters, and then the function body. Functions in ECMAScript do not need to specify whether to return a value. Any function can use the return statement at any time to return the value of the function, followed by the value to be returnedThe function sum() will add the two values and return the result. Note that there is no special declaration other than the return statement that the function has a return value
Strict mode also has some restrictions on functions:The function cannot be named eval or arguments;
The parameters of the function cannot Call eval or arguments;The parameters of two functions cannot be called with the same name.
8. Variables, scope and memory
4-1. Original value and reference value
ECMAScript variables can Contains two different types of data: primitive values and reference values. Primitive value is the simplest data, and reference value is an object composed of multiple values.
When assigning a value to a variable, the JavaScript engine must determine whether the value is a primitive value or a reference value. The previous chapter discussed 6 primitive values: Undefined, Null, Boolean, Number, String and Symbol. Variables that hold raw values are accessed by value because we are operating on the actual value stored in the variable.The reference value is an object stored in memory. Unlike other languages, JavaScript does not allow direct access to memory locations, so it cannot directly operate on the memory space where the object is located. When operating an object, what is actually operated is the reference to the object rather than the actual object itself. For this purpose, the variable holding the reference value is accessed by reference.
Note: In many languages, strings are represented using objects and are therefore considered reference types. ECMAScript breaks this convention. Dynamic properties The definition of original value and reference value is very similar. They both create a variable and then assign a value to it. However, what can be done with the value after the variable holds it is quite different. For reference values, you can add, modify and delete their properties and methods at any time
When passing parameters by value, the value will be copied to a local variable (that is, a named parameter, or in ECMAScript parlance, a slot in the arguments object). When passing parameters by reference, the location of the value in memory will be saved in a local variable, which means that modifications to the local variable will be reflected outside the function
By definition, all reference values are instances of Object, so any reference value detected through the instanceof operator and the Object constructor will return true . Similarly, if you use instanceof to detect a primitive value, it will always return false because the primitive value is not an object.
Note that the typeof operator also returns "function" when used to detect functions. When used to detect regular expressions in Safari (until Safari 5) and Chrome (until Chrome 7), due to implementation details, typeof also returns "function" . ECMA-262 states that any object that implements the internal [[Call]] method should return "function" on typeof detection. Because regular expressions in the above browsers implement this method, typeof also returns "function" for regular expressions. In IE and Firefox, typeof returns "object" for regular expressions.
4-2. Execution context and scope
The concept of execution context (herein referred to as "context") is very important in JavaScript. The context of a variable or function determines what data they can access, and how they behave. Each context has an associated variable object, and
all variables and functions defined in this context exist on this object. Although the variable object cannot be accessed through code, it is used to process data in the background.
The global context is the outermost context. Depending on the host environment of the ECMAScript implementation, the object representing the global context may be different. In the browser, the global context is what we often call the window object (will be introduced in detail in Chapter 12), so all global variables and functions defined through
var will become properties and methods of the window object. Top-level declarations using let and const are not defined in the global context, but have the same effect on scope chain resolution. The context will be destroyed after all its code has been executed, including all variables and functions defined on it (the global context will not be destroyed until the application exits, such as closing the web page or exiting the browser).
Each function call has its own context. When code execution flow enters a function, the function's context is pushed onto a context stack. After the function is executed, the context stack will pop the function context and return control to the previous execution context. ECMAScript
The execution flow of the program is controlled through this context stack. When the code in the context is executed, it creates a scope chain of variable objects. This scope chain determines the order in which variables and functions are accessed by code at each level of context. The variable object of the context in which the code is executing is always at the front of the scope chain. If the context is a function, its activation object is used as the variable object. The active object initially has only one defined variable: arguments. (There is no such variable in the global context.) The next variable object in the scope chain comes from the containing context, and the next object comes from the containing context after that. And so on until the global context; the variable object of the global context is always the last variable object of the scope chain
Scope chain enhancement
Although the execution context mainly includes the global context and functions There are two contexts (a third context exists inside the eval() call), but there are other ways to enhance the scope chain. Certain statements cause a context to be temporarily added at the front of the scope chain, which is removed after code
is executed.
Variable declaration
After ES6, JavaScript variable declaration has undergone earth-shaking changes. Until
ECMAScript 5.1, var was the only keyword for declaring variables. ES6 not only adds
let and const keywords, but also makes these two keywords overwhelmingly surpass
var as the first choice.
Function scope declaration using var
When declaring a variable using var, the variable is automatically added to the closest context. Within a function, the closest context is the function's local context. In a with statement, the closest context is also the function context. If a variable is initialized without declaring it, it will automatically be added to the global contextNote: Initializing a variable without declaring it is a very common mistake in JavaScript programming and can cause many problems. For this reason, readers must declare variables before initializing them. In strict mode, initializing a variable without declaring it will result in an error
The var declaration will be moved to the top of the function or global scope, before all code in the scope. This phenomenon is called "hoisting". Hoisting allows code in the same scope to use the variable without having to worry about whether it has been declared. However, in practice, promotion can also lead to the legal but strange phenomenon of using variables before they are declared.
Use let's block-level scope declaration
The new let keyword in ES6 is very similar to var, but its scope is block-level, which is also the case in JavaScript new concept. Block-level scope is delimited by the nearest pair of curly braces {}. In other words, if blocks, while blocks, function blocks, and even individual blocks are the scope of let declared variables.
Use const constant declaration
In addition to let, ES6 also adds the const keyword. Variables declared using const must also be initialized to a value. Once declared, new values cannot be reassigned at any time during its life cycle
Note that development practice shows that if the development process will not be greatly affected by this, You should use const declarations as much as possible unless you really need a variable that will be reassigned in the future. This can fundamentally ensure that bugs caused by reassignment are discovered in advance
4-3. Garbage collection
JavaScript is a language that uses garbage collection, that is Said execution environment is responsible for managing memory while code is executing. In languages like C and C, tracking memory usage is a big burden on developers and the source of many problems. JavaScript relieves developers of this burden and implements memory allocation and idle resource recycling through automatic memory management. The basic idea is simple: determine which variable will no longer be used, and release the memory it occupies. This process is cyclical, that is, the garbage collection program will run automatically at certain intervals (or at a scheduled collection time during code execution). The garbage collection process is an approximate and imperfect solution, because whether a certain piece of memory is still useful is an "undecidable" problem, which means that it cannot be solved by algorithms.
We take the normal life cycle of local variables in a function as an example. Local variables in a function will exist when the function is executed. At this time, stack (or heap) memory will allocate space to save the corresponding value. The function uses variables internally and then exits. At this point, the local variable is no longer needed, and the memory it occupies can be released for later use. It's obvious that local variables are no longer needed in this case, but it's not always obvious. The garbage collector must keep track of which variables are still used and which variables are no longer used in order to reclaim memory. There may be different implementations of how to mark unused variables. However, in the history of browser development, two main markup strategies have been used: markup sanitization and reference counting.
Mark Sweep
The most commonly used garbage collection strategy in JavaScript is mark-and-sweep. When a variable enters the context, such as declaring a variable inside a function, the variable is marked as existing in the context. Variables that are not in the context, logically, should never release their memory, because they may be used as long as the code in the context is running. When a variable leaves context, it is also marked as leaving context.
There are many ways to tag variables. For example, when a variable enters the context, invert a certain bit; or you can maintain two lists of variables "in context" and "not in context", and you can move variables from one list to the other. The implementation of the marking process is not important, the key is the strategy.
When the garbage collection program runs, it will mark all variables stored in memory (remember, there are many ways to mark). It then removes the tags from all variables in the context, as well as variables referenced by variables in the context. Variables that are marked after this are for deletion because they are no longer accessible to any variables in the context. The garbage collector then performs a memory cleanup, destroying all marked values and reclaiming their memory.
By 2008, IE, Firefox, Opera, Chrome, and Safari all used markup cleaning (or variations thereof) in their JavaScript implementations, differing only in how often they ran garbage collection.
Reference Counting
Another less commonly used garbage collection strategy is reference counting. The idea is to record for each value the number of times it has been referenced. When you declare a variable and assign a reference value to it, the reference number of this value is 1. If the same value is assigned to another variable, the reference number is increased by 1. Similarly, if the variable holding a reference to the value is overwritten by another value, the reference count is decremented by one. When the reference count of a value is 0, it means that the value can no longer be accessed, so its memory can be safely reclaimed. The garbage collection program
will release the memory with a reference number of 0 the next time it runs. Reference counting was first adopted by Netscape Navigator 3.0, but soon encountered a serious problem: circular references. The so-called circular reference means that object A has a pointer pointing to object B, and object B also refers to object A.
To be updated. . .
Related free learning recommendations: javascript (video)
The above is the detailed content of Record JavaScript study notes. For more information, please follow other related articles on the PHP Chinese website!