JavaScript Advanced Programming (4th edition) Reading Notes

Chapter 3 _ Language Basics

This paper mainly

  • ECMAScript has six simple data types: Undefined, Null, Boolean, Number, String, and Symbol. Different data types have their own special properties and methods. We should be familiar with the previous five types, so we focus on Symbol. There is a link in the following article, so we can have a good study of this new data type.
  • Different data types can be determined according to typeOf.
  • (1)typeof is an operator followed by a unary expression and returns the data typeof that expression. The returned result with this type of string (all lowercase) form, including the number, string, Boolean, undefined, object, function, symbol, etc.
  • (2)instanceof is used to determine whether A is an instanceof B. The expression is: A instanceof B, true if A is an instanceof B, false otherwise. Instanceof detects prototypes, and the internal mechanism is to determine whether there are types of prototypes in an object’s prototype chain.
  • (3) When a function F is defined, the JS engine adds a prototype to F, then adds a constructor property to prototype and references it to F. F uses the constructor property to refer to itself. The constructor attribute on the stereotype is inherited from the newly created object, and from the stereotype chain perspective, the constructor F is the type of the new object. The idea is to have a traceable data type as soon as the object is born.
  • (4) the Object. The prototype. The toString (), toString () method was the prototype of the Object, this method is invoked, the default [[Class]] returns the current Object. This is an internal property of the form [object Xxx], where Xxx is the type of the object. For Object objects, toString() returns Object Object. For other objects, call and apply are required to return the correct type information.
  • JS operators are divided into many kinds, in fact, from I think we are familiar with the common, but here the bit operator is really novel for me, before has not understood this concept, this time just learned.
  • There are a lot of JavaScript statements, and most of them are the ones we use most of the time, but I don’t use label, break,continue very often, so be careful when you look at them.
  • JavaScript functions this chapter is only a brief introduction, and there is no detailed explanation, should be a detailed study in the later chapter.

3.4 Data Types

ECMAScript has six simple data types (also known as primitive types) : Undefined, Null, Boolean, Number, String, and Symbol. Symbol is new to 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. Having only seven data types seems inadequate to represent all data. But ECMAScript’s data types are flexible, and one data type can be used as multiple data types.

3.4.1 Typeof operator

Determine the data type of any variable. Using the Typeof operator on a value returns one of the following strings:

  • “Undefined” indicates undefined value;
  • “Boolean” indicates that the value is Boolean;
  • “String” indicates that the value is a string;
  • “Number” indicates a numerical value.
  • “Object” indicates that the value is an object (not a function) or null;
  • “Function” means the value is a function;
  • “Symbol” means the value is a symbol

Note that because Typeof is an operator and not a function, no arguments are required (but arguments can be used). Typeof returns results that can be confusing in some cases, but are technically correct. For example, calling Typeof NULL returns “object”. This is because the special value null is considered a reference to an empty object.

3.4.2 Undefined type

Undefined 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 undefined value to the variable (because by default, any uninitialized variable takes undefined value) :

let message; 
console.log(message == undefined); // true 
Copy the code

There is a difference between a variable that contains undefined and an undefined variable. Look at the following example:

let message;    // This variable is declared with undefined
// Make sure that this variable is not declared
// let age 
console.log(message); // "undefined" 
console.log(age);     / / an error
Copy the code

Calling typeof on an uninitialized variable returns “undefined”, but calling it on an undeclared variable returns “undefined”, which is a bit confusing. Take the following example:

let message; // This variable is declared with undefined
// Make sure that this variable is not declared
// let age 
console.log(typeof message); // "undefined"
console.log(typeof age);     // "undefined" 
Copy the code

Whether declared or undeclared, Typeof returns the string “undefined”. This is logically correct, because while strictly speaking these two variables are fundamentally different, neither of them can actually perform operations.

Rule 3.4.3 Null type

The Null type also has only one value, the special value Null. Logically, a null value represents an empty object pointer, which is why passing a null to typeof returns “object” :

let car = null;
console.log(typeof car);  // "object" 
Copy the code

When defining variables that will hold object values in the future, it is recommended to use NULL for initialization and not other values. If the value of the variable is null, you can tell if the variable was later assigned a reference to an object, for example:

if(car ! =null) { 
// Car is a reference to an object
} 
Copy the code

Undefined values are derived from null values, so ECMA-262 defines them as ostensibly equal, as shown in the following example:

console.log(null= =undefined);  // true
Copy the code

Comparing null and undefined with the equal operator (==) always returns true. You never have to explicitly set the variable value to undefined. But null doesn’t work like that. Any time a variable wants to hold an object and there is no object available at the time, null is used to fill the variable. This preserves the semantics of null as an empty object pointer and further distinguishes it from undefined.

3.4.4 Boolean type

The Boolean type is one of the most frequently used types in ECMAScript and has two literals: true and false. These two Booleans are different from numeric values, so true is not equal to 1 and false is not equal to 0.

Note that the Boolean literals true and false are case sensitive, so true and false (and other size mashups) are valid identifiers, but not Booleans.

To convert a value of another type to a Boolean, call the special Boolean() transformation function:

let message = "Hello world!";
let messageAsBoolean = Boolean(message);
Copy the code

Boolean() The transformation function can be called on any type of data and always returns a Boolean value. The rules for what values can be converted to true or false depend on the data type and the actual value. The following table summarizes the conversion rules between different types and Booleans.

3.4.5 Number type

The Number type uses IEEE 754 format to represent integer and floating point values (also called double values in some languages). Different numeric types have different numeric literal formats accordingly.

The basic numeric literal format is a decimal integer, and values created using octal and hexadecimal formats are treated as decimal values in all mathematical operations. Positive zeros (+0) and negative zeros (0) can exist in practice because of the way JavaScript holds values. Positive zero and negative zero are considered equal in all cases.

1. The floating point value

To define a floating point value, the value must contain a decimal point, and there must be at least one digit after the decimal point. The decimal point is not necessarily preceded by an integer, but it is recommended. Here are a few examples:

let floatNum1 = 1.1; 
let floatNum2 = 0.1; 
let floatNum3 = 1.;   // Valid, but not recommended
Copy the code

Because storing floating-point values uses twice as much memory as storing integer values, ECMAScript always tries to convert values to integers. When there are no numbers after the decimal point, the value becomes an integer. Similarly, if the value itself is an integer followed by a 0 (such as 1.0), it will be converted to an integer, as shown in the following example:

let floatNum1 = 1.;   // If there is no number after the decimal point, it is treated as an integer 1
let floatNum2 = 10.0; // If the decimal point is followed by zero, it is treated as an integer 10
Copy the code

Floating-point values can be expressed in scientific notation for very large or very small values. Scientific notation is used to represent a number that should be multiplied by a given power of 10. The format of scientific notation in ECMAScript requires that a numeric value (integer or floating point) be followed by an uppercase or lowercase letter E, plus a power of 10 to be multiplied. Such as:

let floatNum = 3.125 e7; / / equal to 31250000
Copy the code

Floating-point values are accurate to up to 17 decimal places, but far less accurate in arithmetic than integers. For example, instead of adding 0.2 to 0.1, you get 0.300 000 000 000 000 04. This tiny rounding error makes it difficult to test specific floating point values. Often interview questions are based on this point

2. Value range

Due to memory limitations, ECMAScript does not support representing all values in the world. Small ECMAScript values are stored in number.min_value, which in most browsers is 5E-324; The large Number that can be represented is stored in number.max_value, which in most browsers is 1.797 693 134 862 315 7e+308. If a numerical result of a calculation is out of the range that JavaScript can represent, the value is automatically converted to a special Infinity value. Any unrepresented negative numbers are represented by -infinity, and any unrepresented positive numbers are represented by Infinity.

If the calculation returns positive Infinity or negative Infinity, the value cannot be used in any further calculation. This is because Infinity has no numerical representation that can be computed. To determine if a value isFinite(that is, between the small and large values that JavaScript can represent), use the isFinite() function, as shown below:

let result = Number.MAX_VALUE + Number.MAX_VALUE; 
console.log(isFinite(result));  // false
Copy the code

Computations beyond finite values are rare, but they are always possible. Therefore, when calculating very large or very small values, it is necessary to monitor whether the results are out of range.

3. NaN

A special value called NaN, which means “Not a Number,” is used to indicate that an operation that was supposed to return a Number failed (rather than throw an error). For example, dividing 0 by any value in other languages usually results in an error that stops code execution. But in ECMAScript, dividing 0, +0, or -0 returns NaN:

console.log(0/0);    // NaN 
console.log(-0/+0);  // NaN 
Copy the code

If the numerator is non-zero and the denominator is signed or unsigned 0, Infinity or -infinity is returned:

console.log(5/0);   // Infinity 
console.log(5/-0);  // -Infinity 
Copy the code

NaN has several unique attributes. First, any operation that involves a NaN always returns a NaN (such as NaN/10), which can be a problem in successive multi-step calculations. Second, NaN is not equal to any value including NaN.

console.log(NaN= =NaN); // false 
Copy the code

For this purpose, ECMAScript provides the isNaN() function. This function takes an argument, which can be of any data type, and determines whether the argument is “not a number.” After passing a value to isNaN(), the function attempts to convert it to a numeric value. Some non-numeric values can be converted directly to numeric values, such as the string “10” or a Boolean value. Any value that cannot be converted to a numeric value causes this function to return true. Examples are as follows:

console.log(isNaN(NaN));     // true 
console.log(isNaN(10));      // false, 10 is a number
console.log(isNaN("10"));    // false, which can be converted to the value 10
console.log(isNaN("blue"));  // true, cannot be converted to a numeric value
console.log(isNaN(true));    // false, which can be converted to the value 1
Copy the code

Although not common, isNaN() can be used to test objects. At this point, the valueOf() method of the object is called first, and then the returned value can be converted to a numeric value. If not, call the toString() method again and test its return value.

4. Numerical conversion

There are three functions to convert non-numeric values to numeric values: Number(), parseInt(), and parseFloat(). Number() is a transformation function that can be used for any data type. The latter two functions are mainly used to convert strings to numbers. The three functions also perform different operations on the same arguments. The Number() function performs the conversion based on the following rules.

  • Boolean values that convert true to 1 and false to 0.
  • Value, return directly.
  • Null returns 0.
  • Undefined, return NaN.
  • String, apply the following rules:
    • If the string contains numeric characters, including those preceded by plus or minus signs, it is converted to a decimal value. Therefore, Number(“1”) returns 1, Number(“123”) returns 123, and Number(“011”) returns 11 (ignoring the preceding zeros).
    • If the string contains a valid floating-point value format such as “1.1”, it is converted to the corresponding floating-point value (again, the preceding zeros are ignored).
    • If the string contains a valid hexadecimal format such as “0xf”, it is converted to the decimal integer value corresponding to the hexadecimal value.
    • If it is an empty string (containing no characters), 0 is returned.
    • If the string contains characters other than the above, NaN is returned.
  • Object that calls the valueOf() method and converts the returned value according to the rules above. If the conversion results in a NaN, the toString() method is called and converted according to the rules for converting strings.

Here are a few specific examples:

let num1 = Number("Hello world!");  // NaN 
let num2 = Number("");              / / 0
let num3 = Number("000011");        / / 11
let num4 = Number(true);            / / 1
Copy the code

Given the complexity and unconventionality of converting strings using the Number() function, parseInt() is usually preferred when an integer is needed. The parseInt() function focuses more on whether the string contains a numeric pattern. Spaces before the string are ignored, and the conversion begins with the first non-space character. If the first character is not a numeric character, plus or minus, parseInt() immediately returns NaN. This means that an empty string also returns NaN (unlike Number(), which returns 0). If the first character is a numeric character, plus or minus, each character in turn is tested until the end of the string, or a non-numeric character is encountered. For example, “1234blue” would be converted to 1234 because “blue” would be completely ignored. Similarly, “22.5” is converted to 22 because the decimal point is not a valid integer character.

The parseInt() function also recognizes different integer formats (decimal, octet, hexadecimal), assuming that the first character in the string is a numeric character. In other words, if a string begins with “0x”, it is interpreted as a hexadecimal integer. If a string begins with “0” and is followed by a numeric character, it is interpreted by some implementations as an octal integer in non-strict mode. Here’s an example:

let num1 = parseInt("1234blue");  / / 1234
let num2 = parseInt("");          // NaN
let num3 = parseInt("0xA");       // 10, interpreted as a hexadecimal integer
let num4 = parseInt(22.5);        / / 22
let num5 = parseInt("70");        // 70 is interpreted as a decimal value
let num6 = parseInt("0xf");       // 15, interpreted as a hexadecimal integer
Copy the code

Different numeric formats can be confusing, so parseInt() also takes a second argument that specifies the base (base). If a base argument is provided, identifiers such as “0x” at the beginning of the string can be omitted:

let num = parseInt("0xAF".16); / / 175
let num1 = parseInt("AF".16);  / / 175
let num2 = parseInt("AF");      // NaN 
Copy the code

The parseFloat() function works like parseInt() in that it detects each character from position 0. Again, it is resolved to the end of the string or to an invalid floating-point numeric character. This means that the first occurrence of the decimal point is valid, but the second occurrence is invalid, and the rest of the string is ignored. Therefore, “22.34.5” will be converted to 22.34. The parseFloat() function is also different in that it always ignores the zero at the beginning of the string. This function recognizes all floating-point formats discussed earlier, as well as decimal formats (starting zeros are always ignored). Hexadecimal values always return 0. Because parseFloat() only parses decimal values, you cannot specify a base. Finally, parseFloat() returns an integer if the string represents an integer (with no decimal point or only a zero after the decimal point).

let num1 = parseFloat("1234blue");  // 1234, parsed as an integer
let num2 = parseFloat("0xA");       / / 0
let num3 = parseFloat("22.5");      / / 22.5
let num4 = parseFloat("22.34.5");   / / 22.34
let num5 = parseFloat("0908.5");    / / 908.5
let num6 = parseFloat("3.125 e7");   / / 31250000
Copy the code

3.4.6 type String

The String data type represents a sequence of zero or more 16-bit Unicode characters. Strings can be marked with double quotes (“), single quotes (‘), or backquotes (‘), so the following code is legal:

let firstName = "John";
let lastName = 'Jacob'; 
let lastName = `Jingleheimerschmidt`
Copy the code

A string that begins with a quotation mark must still end with that quotation mark.

1. character literals

String data types contain character literals that represent non-print characters or characters for other purposes, as shown in the following table:

These character literals can appear anywhere in the string and can be interpreted as a single character, and the length of the string can be obtained by its length attribute:

let text = "This is the letter sigma: \u03a3.";
console.log(text.length); / / 28
Copy the code

2. Characteristics of strings

Strings in ECMAScript are immutable, meaning that their values cannot be changed once created. To change a string value in a variable, you must first destroy the original string and then save another string containing the new value to the variable, as follows:

let lang = "Java"; 
lang = lang + "Script"; 
Copy the code

Here, the variable lang starts with the string “Java”. Next, lang was redefined to contain a combination of “Java” and “Script”, i.e., “JavaScript”. The process first allocates a space large enough to hold 10 characters, and then populates “Java” and “Script”. The original string “Java” and string “Script” are destroyed because both strings are no longer useful.

3. Convert to a string

There are two ways to convert a value to a string. The first is to use the toString() method, which is available for almost all values. The only use of this method is to return the string equivalent of the current value. Such as:

let age = 11; 
let ageAsString = age.toString();      // String "11"
let found = true;
let foundAsString = found.toString();  // String "true"
Copy the code

The toString() method is visible on numeric, Boolean, object, and string values. (Yes, string values also have a toString() method, which simply returns a copy of itself.) Null and undefined have no toString() method.

In most cases, toString() takes no arguments. However, when calling this method on a value, toString() can take a base argument, which is the string representation of the value to output at. By default, toString() returns a decimal string representation of a numeric value. By passing in an argument, you get a string representation of the numeric value in binary, octal, hexadecimal, or any other valid base, and by default (with no argument) the output is the same as if you passed in the argument 10. Such as:

let num = 10; 
console.log(num.toString());     10 "/ /"
console.log(num.toString(2));    / / "1010"
console.log(num.toString(8));    / / "12"
console.log(num.toString(10));   10 "/ /"
console.log(num.toString(16));   // "a"
Copy the code

If you are not sure whether a value is null or undefined, you can use the String() function, which always returns a String representing the value of the corresponding type. The String() function follows these rules.

  • If the value has a toString() method, that method is called (with no arguments) and the result is returned.
  • If the value is null, return “null”.
  • Return “undefined” if the value is undefined.

4. Template literals

ECMAScript 6 adds the ability to define strings using template literals. Unlike single or double quotes, template literals retain newline characters and can define strings across lines. (Because template literals retain Spaces inside backquotes, be careful when using them. A well-formed template string might look indented incorrectly) :

let myMultiLineString = 'first line\nsecond line'; 
let myMultiLineTemplateLiteral = `first line second line`; 
 
console.log(myMultiLineString); 
// first line
// second line" 
 
console.log(myMultiLineTemplateLiteral); 
// first line 
// second line 
 
console.log(myMultiLineString === myMultiLinetemplateLiteral); // true
Copy the code

5. String interpolation

A common feature of template literals is support for string interpolation, where one or more values can be inserted into a contiguous definition. Technically, a template literal is not a string, but a special JavaScript syntactic expression that evaluates to a string. All inserted values are coerced into strings using toString(), and any JavaScript expression can be used for interpolation. Nested template strings do not need to be escaped.

let value = 5; 
let exponent = 'second'; 
// Previously, string interpolation was implemented like this:
let interpolatedString =   value + ' to the ' + exponent + ' power is ' + (value * value); 
 
// Now, template literals can be implemented like this:
let interpolatedTemplateLiteral =   `${ value } to the ${ exponent } power is ${ value * value }`; 
 
console.log(interpolatedString);           // 5 to the second power is 25 
console.log(interpolatedTemplateLiteral);  // 5 to the second power is 25 
Copy the code

6. Template literals tag functions

Template literals also support defining tag functions that allow you to customize the interpolation behavior. The label function receives the template separated by the interpolation notation and the result of evaluating each expression.

let a = 6; 
let b = 9;  
 
function simpleTag(strings, aValExpression, bValExpression, sumExpression) {  
console.log(strings);  
console.log(aValExpression); 
console.log(bValExpression);  
console.log(sumExpression); 
return 'foobar'; 
} 
 
let untaggedResult = `${ a } + ${ b } = ${ a + b }`; 
let taggedResult = simpleTag`${ a } + ${ b } = ${ a + b }`; // ["", "+ "," = ", "] // 6 // 9 // 15
 
console.log(untaggedResult);   // "6 + 9 = 15"
console.log(taggedResult);     // "foobar" 
Copy the code

7. Raw string

Template literals can also be used to retrieve the original template literal content (such as newlines or Unicode characters) rather than the converted character representation. To do this, you can use the default string. raw tag function:

/ / Unicode example
// \u00A9 is a copyright symbol
console.log(`\u00A9`);            / / ©
console.log(String.raw`\u00A9`);  // \u00A9 
 
// The newline example
console.log(`first line\nsecond line`);
// first line 
// second line 
 
console.log(String.raw`first line\nsecond line`); // "first line\nsecond line" 
 
// Not for actual newlines // they will not be converted to escape sequences
console.log(`first line second line`); // first line // second line 
 
console.log(String.raw`first line second line`); // first line // second line 
Copy the code

3.4.7 Symbol type

Symbol is a new data type in ECMAScript 6. Symbols are primitive values, and symbol instances are unique and immutable. The purpose of the symbol is to ensure that object attributes are uniquely identified without the risk of attribute collisions.

Although it may sound similar to private properties, symbols are not added to provide the behavior of private properties (especially because the Object API provides methods that make it easier to discover symbolic properties). Instead, symbols are used to create unique tokens that can then be used as non-string object attributes.

1. Basic usage of symbols

Symbols need to be initialized using the Symbol() function. Because symbols themselves are primitive types, the Typeof operator returns symbol for symbols.

let sym = Symbol(a);console.log(typeof sym); // symbol
Copy the code

When we call the Symbol() function, we can also pass in a string argument as a description of the Symbol, which we can use to debug our code in the future. However, this string argument has nothing to do with symbol definition or identity at all:

let genericSymbol = Symbol(a);let otherGenericSymbol = Symbol(a);let fooSymbol = Symbol('foo'); 
let otherFooSymbol = Symbol('foo'); 
 
console.log(genericSymbol == otherGenericSymbol);  // false 
console.log(fooSymbol == otherFooSymbol);          // false 
Copy the code

Symbols don’t have literal syntax, which is what makes them useful. Creating an instance of Symbol() and using it as a new attribute of the object ensures that it does not overwrite existing object attributes, whether symbolic or string.

let genericSymbol = Symbol(a);console.log(genericSymbol);  // Symbol() 
 
let fooSymbol = Symbol('foo'); 
console.log(fooSymbol);      // Symbol(foo);
Copy the code

Importantly, the Symbol() function cannot be used as a constructor with the new keyword. This is done to avoid creating symbolic wrapper objects like with Boolean, String, or Number, which all support constructors and can be used to initialize wrapped objects that contain original values.

let myBoolean = new Boolean(a);console.log(typeof myBoolean); // "object" 
 
let myString = new String(a);console.log(typeof myString);  // "object" 
 
let myNumber = new Number(a);console.log(typeof myNumber);  // "object" 
 
let mySymbol = new Symbol(a);// TypeError: Symbol is not a constructor 
// If you really want to wrap objects with symbols, you can use the Object() function:
let mySymbol = Symbol(a);let myWrappedSymbol = Object(mySymbol); 
console.log(typeof myWrappedSymbol);   // "object" 
Copy the code

2. Use the global symbol registry

If different parts of the runtime need to share and reuse symbol instances, symbols can be created and reused in the global symbol registry using a string as the key. To do this, use the symbol.for () method:

let fooGlobalSymbol = Symbol.for('foo');
console.log(typeof fooGlobalSymbol); // symbol 
Copy the code

Symbol.for() performs an idempotent operation on each string key. The first time a string is called, it checks the global runtime registry and finds that no corresponding symbol exists, so a new symbol instance is generated and added to the registry. Subsequent calls to the same string also check the registry for a symbol corresponding to the string, and return an instance of that symbol.

let fooGlobalSymbol = Symbol.for('foo');       // Create a new symbol
let otherFooGlobalSymbol = Symbol.for('foo');  // Reuse existing symbols
 
console.log(fooGlobalSymbol === otherFooGlobalSymbol);  // true 

let localSymbol = Symbol('foo'); 
let globalSymbol = Symbol.for('foo'); 
 
console.log(localSymbol === globalSymbol); // false 
Copy the code

Symbols in the global registry must be created using string keys, so any value passed as an argument to symbol.for () is converted to a string. In addition, the keys used in the registry are also used as symbolic descriptions.

let emptyGlobalSymbol = Symbol.for(); 
console.log(emptyGlobalSymbol);    // Symbol(undefined)
Copy the code

You can also query the global registry using symbol.keyfor (), which takes a Symbol and returns the string key corresponding to that global Symbol. If the query is not global, undefined is returned.

// Create a global symbol
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s));   // foo 
 
// Create a normal symbol
let s2 = Symbol('bar');
console.log(Symbol.keyFor(s2));  // undefined 
// If the Symbol passed to symbol.keyfor () is not a Symbol, the method raises TypeError:
Symbol.keyFor(123); // TypeError: 123 is not a symbol 
Copy the code

3. Use symbols as attributes

Wherever you can use strings or values as attributes, you can use symbols. This includes Object literal properties and properties defined by Object.defineProperty()/Object.defineProperties(). Object literals can only use symbols as attributes in the computed attribute syntax.

let s1 = Symbol('foo'),   
s2 = Symbol('bar'),   
s3 = Symbol('baz'),  
s4 = Symbol('qux'); 
 
let o = {   [s1]: 'foo val' };
O [s1] = 'foo val';
 
console.log(o); 
// {Symbol(foo): foo val} 
 
Object.defineProperty(o, s2, {value: 'bar val'}); 
 
console.log(o); 
// {Symbol(foo): foo val, Symbol(bar): bar val} 
 
Object.defineProperties(o, {  
[s3]: {value: 'baz val'}, 
[s4]: {value: 'qux val'}});console.log(o); 
// {Symbol(foo): foo val, Symbol(bar): bar val, 
// Symbol(baz): baz val, Symbol(qux): qux val}
Copy the code

Similar to the Object. GetOwnPropertyNames () returns an Object instance of conventional attribute array, Object. GetOwnPropertySymbols array of symbols () returns an Object instance attributes. The return values of these two methods are mutually exclusive. Object. GetOwnPropertyDescriptors () will return to contain both conventional and symbolic attributes descriptor Object. Reflect.ownkeys () returns two types of keys:

let s1 = Symbol('foo'),  
s2 = Symbol('bar');  
 
let o = {   
[s1]: 'foo val',  
[s2]: 'bar val'.baz: 'baz val'.qux: 'qux val' 
}; 
 
console.log(Object.getOwnPropertySymbols(o)); 
// [Symbol(foo), Symbol(bar)] 
 
console.log(Object.getOwnPropertyNames(o));
// ["baz", "qux"] 
 
console.log(Object.getOwnPropertyDescriptors(o)); 
// {baz: {... }, qux: {... }, Symbol(foo): {... }, Symbol(bar): {... }}
 
console.log(Reflect.ownKeys(o)); 
// ["baz", "qux", Symbol(foo), Symbol(bar)] 
Copy the code

Because a symbol attribute is a reference to an in-memory symbol, symbols created directly and used as attributes are not lost. However, if references to these attributes are not explicitly saved, then all symbolic attributes of the object must be traversed to find the corresponding attribute key (that is, to find the corresponding attribute) :

let o = {   
[Symbol('foo')]: 'foo val'[Symbol('bar')]: 'bar val'
}; 
 
console.log(o); 
// {Symbol(foo): "foo val", Symbol(bar): "bar val"} 
 
let barSymbol = Object.getOwnPropertySymbols(o).find((symbol) = > symbol.toString().match(/bar/)); 
 
console.log(barSymbol); // Symbol(bar)
Copy the code

4. Common built-in symbols

ECMAScript 6 also introduces a number of commonly used built-in symbols that expose language behavior that developers can directly access, rewrite, or emulate. These built-in symbols all exist as string properties of the Symbol factory function. One important use of these built-in symbols is to redefine them to change the behavior of the native structure. For example, if we know that a for-of loop uses the symbol. iterator property on related objects, we can change the behavior of for-of when iterating over that object by redefining the value of symbol. iterator on a custom object. There’s nothing special about these built-in symbols, either; they’re just plain string attributes of the global function Symbol, pointing to an instance of a Symbol. All built-in symbolic properties are not writable, enumerable, or configurable

Other attributes and methods of Symbol are more detailed here. And this one is a little confusing to me. Symbol explanation

3.4.8 Object type

An object in ECMAScript is simply a collection of data and functionality. Objects are created by the new operator followed by the name of the object type. Developers can create their own objects by creating instances of type Object and then adding properties and methods to the objects:

let o = new Object(a);let o = new Object;  // Legal, but not recommended
Copy the code

Each Object instance has the following properties and methods.

  • Constructor: The function used to create the current object. In the previous example, the value of this property was the Object() function.
  • HasOwnProperty (propertyName) : Used to determine whether a given property exists on the current object instance (not the prototype). The property name to be checked must be a string (such as O.hasownProperty (“name”)) or a symbol.
  • IsPrototypeOf (object) : Used to determine whether the current object is the prototype of another object. (Chapter 8 covers prototypes in more detail.)
  • PropertyIsEnumerable (propertyName) : Used to determine if a given property can be enumerable in a for-in statement (discussed later in this chapter). As with hasOwnProperty(), the property name must be a string.
  • ToLocaleString () : Returns a string representation of an object that reflects its localized execution environment.
  • ToString () : Returns a string representation of an object.
  • ValueOf () : Returns the string, numeric, or Boolean representation of an object. Usually the same as the return value of toString().

Because Object is the base class of all objects in ECMAScript, any Object has these properties and methods.

3.5 the operator

3.5.1 Unary operators

Operators that operate on only one value are called unary operators. Unary operators are simple operators in ECMAScript.

1. Increment/decrement operators

The increment and decrement operators are directly copied from C, but come in two versions: pre and post. As the name implies, the previous version precedes the variable to be manipulated, and the later version precedes the variable to be manipulated. The main difference between the post-version and the pre-version is that the post-version increment and decrement occur after the statement has been evaluated.

The increment and decrement operators follow these rules.

  • For a string, if it is a valid numeric form, convert it to a numeric value and apply the change. The variable type changes from a string to a number.
  • For strings, if it is not a valid numeric form, set the value of the variable to NaN. The variable type changes from a string to a number.
  • For Boolean values, if false, convert to 0 and apply the change. The variable type changes from a Boolean to a numeric value.
  • For booleans, if true, convert to 1 and apply the change. The variable type changes from a Boolean to a numeric value.
  • For floating-point values, add or subtract 1.
  • If it is an object, the valueOf() method (described in more detail in Chapter 5) is called to get a value that can be manipulated. Apply the above rules to the resulting values. In the case of NaN, toString() is called and the other rules are applied again. The variable type changes from object to value.
let num1 = 2; 
let num2 = 20;
let num3 = num1-- + num2; 
let num4 = num1 + num2;
let num5 = ++num1 + num2; 
console.log(num3);  / / 22
console.log(num4);  / / 21
console.log(num5);  / / 22

let s1 = "2"; 
let s2 = "z"; 
let b = false;
let f = 1.1; 
let o = {   valueOf() {     return -1; }}; s1++;// The value becomes the number 3
s2++;  // The value becomes NaN
b++;   // The value becomes 1
f--;   // The value becomes 0.10000000000000009 (because the floating point number is imprecise)
o--;   // The value becomes -2
Copy the code

2. Unary plus and minus

Unary addition is indicated by a plus sign (+) that precedes the variable and has no effect on the value. Unary subtraction, indicated by a minus sign (-), precedes a variable and is mainly used to change a value into a negative value, such as from 1 to -1.

let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = {    valueOf() {     return -1; }}; s1 = -s1;// The value becomes the value -1
s2 = -s2;  // The value becomes the value -1.1
s3 = -s3;  // The value becomes NaN
b = -b;    // The value becomes 0
f = -f;    // 变成-1.1 
o = -o;    // The value becomes 1
Copy the code

3.5.2 bit operators

All values in ECMAScript are stored in ieEE-754 64-bit format, but bitwise operators do not directly manipulate 64-bit values. Instead, the 64-bit value is converted to a 32-bit integer, the operation is performed, and the result is converted back to 64-bit. For signed integers, the first 31 of the 32 bits are used to represent the value of the integer. The 32nd bit is a numeric symbol: 0 for a positive number and 1 for a negative number. The symbol bit is called the symbol bit, and the value of the symbol bit determines the format of the other bit values. Numerical 18 is a binary representation of the 00000000000000000000000000010010 negative also stored as binary code, but the format used is two’s complement. The following three steps are required to compute the binary complement of a numeric value:

  1. Evaluate the binary code of the absolute value of this number (for example, to obtain the binary complement of 18, evaluate the binary code of 18 first);
  2. Find the binary inverse code, that is, replace 0 with 1, replace 1 with 0;
  3. The resulting binary inverse plus one

To obtain the binary code of -18, first obtain the binary code of 18, namely: 0000 0000 0000 0000 0000 0000 0001 0010 and then find the binary code of 18, namely, 0 and 1 swap: 1111 1111 1111 1111 1111 1110 1101 Finally, the binary inverse code plus 1:

You calculate binary representation of the 18, 11111111111111111111111111101110. Note that bit 31 is not accessible when dealing with signed integers. When we print a negative number as a binary string, all we see is that the absolute value of the negative number is preceded by a negative sign in the binary.

var num = -18;
alert(num.toString(2)); / / "- 10010"
Copy the code

To convert the value -18 to a binary string, the result is “-10010”.

1. Bitwise NOT (NOT)

The bitwise nonoperator is represented by a wavy line (~), and the result of executing the bitwise nonoperator is the inverse of the value returned.

var num1 = 25; / / binary 00000000000000000000000000011001
var num2 = ~num1; / / binary 11111111111111111111111111100110
alert(num2); / / - 26
Copy the code

2. (AND)

The bitwise and operator is represented by an ampersand character (&), which has two operator numbers. Bitwise and operations only return 1 if the corresponding bits of both values are 1, and the result is 0 if either bit is 0.

var result = 25 & 3;
alert(result); / / 1
Copy the code

As you can see, the bitwise and operation on 25 and 3 results in 1. Why is that? See the underlying operation:

3. (OR)

The bitwise or operator (|) by a vertical bar symbols, said there are also two operands. Bitwise or operations return 1 if one bit is 1 and 0 only if both bits are 0.

var result = 25 | 3;
alert(result); / / 27
Copy the code

Both of these numbers contain four ones, so you can put each one directly into the result. The binary code 11011 is equal to the decimal value 27.

4. Bitwise XOR

Bitwise xor operators are represented by a caret (^) and also have two operands. Bitwise xor differs from bitwise or in that this operation returns 1 if there is only one 1 in the corresponding bits of the two values, and 0 if both digits are 1 or 0. (Same is 0, different is 1)

var result = 25 ^ 3;
alert(result); / / 26
Copy the code

Both of these numbers have four 1’s, but the first digit is a 1, so the first digit of the result becomes a 0. Any other 1 has no 1 in the other value, so you can just put it in the result. The binary code 11010 is equal to the decimal value 26 (note that this result is 1 less than the bit-or execution).

5. Shift to the left

The left-shift operator, represented by two less-than signs (<<), moves all the bits of a numeric value to the left by the specified number of digits.

var oldValue = 2; // is equal to 10 in binary
var newValue = oldValue << 5; // Is equal to 1000000 in binary and 64 in decimal
Copy the code

Notice that after the shift to the left, there are five more vacancies to the right of the original value. The left-shift operation fills these Spaces with zeros so that the result is a full 32-bit binary number.

Note that the left shift does not affect the sign bits of the operands. In other words, if you move -2 five places to the left, the result will be -64, not 64.

6. Sign right shift

The signed right-shift operator, represented by two greater than signs (>>), moves the value to the right but preserves the sign bit (that is, the sign mark). The signed right-shift operation is the opposite of the left-shift operation, that is, if you move 64 five places to the right, the result will change back to 2:

var oldValue = 64; // is equal to binary 1000000
var newValue = oldValue >> 5; // is equal to 10 in binary, or 2 in decimal
Copy the code

7. Unsigned right shift

The unsigned right-shift operator, represented by three greater than signs (>>>), moves all 32 bits of the value to the right. For positive numbers, an unsigned right shift is the same as a signed right shift. If you move 64 unsigned to the right by 5 bits, the result is still 2:

var oldValue = 64; // is equal to binary 1000000
var newValue = oldValue >>> 5; // is equal to 10 in binary, or 2 in decimal
Copy the code

The unsigned right-shift operator treats a negative binary as a positive binary. Moreover, since negative numbers are represented as the binary complement of their absolute values, the result of an unsigned right shift is very large, as shown in the following example:

var oldValue = -64; / / is 11111111111111111111111111000000 binary
var newValue = oldValue >>> 5; // is equal to 134217726 in decimal
Copy the code

Here, the result is 134217726 when an unsigned 5-bit right shift is performed on -64. Results is so big, because binary code is 11111111111111111111111111000000-64, and the unsigned right shift operation to the binary code as a positive binary code, converted to a decimal is 4294967232. If the value moves to the right 5, 00000111111111111111111111111110, is the result that the decimal 134217726.

3.5.3 Boolean operators

There are three Boolean operators: logical not, logical and logical or.

1. The logic

Logical non-operators consist of an exclamation mark (!). Said. This operator always returns a Boolean, regardless of the data type being applied. A logical nonoperator first converts the operand to a Boolean value and then inverts it.

  • Return false if the operand is an object.
  • Returns true if the operand is an empty string.
  • Return false if the operand is a non-empty string.
  • Returns true if the operand is the value 0.
  • Return false if the operand is a non-zero value (including Infinity).
  • If the operand is null, true is returned.
  • Returns true if the operand is NaN.
  • Returns true if the operand is undefined.

The following example verifies the above behavior:

console.log(!false);   // true
console.log(!"blue");  // false 
console.log(!0);       // true 
console.log(!NaN);     // true 
console.log(!"");      // true 
console.log(!12345);   // false
Copy the code

Use two exclamation points (!!) at the same time , equivalent to calling the transformation function Boolean(). Regardless of the type of operand, the first exclamation mark always returns a Boolean value. The second exclamation mark reverses the Boolean value, giving the true Boolean value of the variable. The result is the same as using the Boolean() function on the same value:

console.log(!!"blue"); // true
console.log(!!0);      // false
console.log(!!NaN);    // false
console.log(!!"");     // false
console.log(!!12345);  // true
Copy the code

2. Logic and

Logic and operators are represented by two ampersand signs (&&). The logic and operator can be used with any type of operand, not limited to Booleans. If an operand is not a Boolean, the logical sum does not necessarily return a Boolean, but follows the following rule.

  • If the first operand is an object, return the second operand.
  • If the second operand is an object, the object is returned only if the first operand evaluates to true.
  • If both operands are objects, return the second operand.
  • If one of the operands is NULL, null is returned.
  • NaN is returned if one of the operands is NaN.
  • Returns undefined if one of the operands is undefined.

The logical and operator is a short-circuit operator, meaning that if the first operand determines the result, the second operand is never evaluated. For logic and operators, if the first operand is false, the result cannot be true regardless of the value of the second operand.

3. The logical or

Logic or the operator by two pipe (| |) said that (there is true) and logic and similar, if one operand is not a Boolean value, so the logic or the operator does not necessarily return Boolean value. It follows the following rules.

  • Returns the first operand if the first operand is an object.
  • If the first operand evaluates to false, the second operand is returned.
  • If both operands are objects, return the first operand.
  • If both operands are null, null is returned.
  • If both operands are NaN, NaN is returned.
  • If both operands are undefined, undefined is returned.

Similarly to logic, logic or operators have the property of short-circuiting. Only for logic, if the first operand evaluates to true, the second operand will not be evaluated.

3.5.4 Multiplicative operator

ECMAScript defines three multiplication operators: multiplication, division, and modulo. These operators do what their Java, C, and Perl counterparts do, but they also include some automatic type conversions for non-numeric values. If the multiplicative operator has an operand that is not a Number, that operand is converted to a Number behind the scenes using the Number() transformation function. This means that the empty string is treated as a 0, and the Boolean true is treated as a 1.

1. Multiplication operator

The multiplication operator is represented by an asterisk (*) and can be used to compute the product of two numeric values.

  • If the operands are both numeric, the usual multiplication is performed, that is, two positive values multiplied together are positive, two negative values multiplied together are positive, and values with different signs multiplied together are negative. If ECMAScript cannot represent a product, Infinity or -infinity is returned.
  • NaN is returned if any of the operands is NaN.
  • If it’s Infinity times 0, NaN is returned.
  • If Infinity is multiplied by a finite number that is not zero, Infinity or -infinity is returned based on the sign of the second operand.
  • If it’s Infinity times Infinity, it returns Infinity.
  • If you have an operand that is not a value, you convert it to a value behind the scenes with Number() before applying the above rules.

2. The division operator

The division operator, represented by a slash (/), calculates the quotient of the first operand divided by the second operand.

  • If the operands are both numeric, then the normal division operation is performed, that is, two positive values divided by two negative values are positive, and two negative values divided by different signs are negative. If ECMAScript cannot represent quotient, Infinity or -infinity is returned.
  • NaN is returned if any of the operands is NaN.
  • If it’s Infinity divided by Infinity, it returns NaN.
  • If it’s 0 divided by 0, NaN is returned.
  • If a nonzero finite value is divided by 0, Infinity or -infinity is returned based on the sign of the first operand.
  • If Infinity is divided by any number, Infinity or -infinity is returned based on the sign of the second operand.
  • If you have an operand that is not a Number, you convert it to a Number behind the scenes using the Number() function before applying the above rules.

3. Fetch operator

The modulo (remainder) operator is represented by a percentage symbol (%).

  • If the operand is numeric, a normal division operation is performed, returning the remainder.
  • If the dividend is infinite and the divisor is finite, NaN is returned.
  • If the dividend is finite and the divisor is 0, NaN is returned.
  • If it’s Infinity divided by Infinity, it returns NaN.
  • Returns the dividend if the dividend is finite and the divisor is infinite.
  • If the dividend is 0 and the divisor is not 0, 0 is returned.
  • If you have an operand that is not a Number, you convert it to a Number behind the scenes using the Number() function before applying the above rules.

3.5.5 Exponential operators

ECMAScript 7 adds the index operator, math.pow () now has its own operator **, the result is the same:

console.log(Math.pow(3.2);    / / 9
console.log(3 ** 2);           / / 9
 
console.log(Math.pow(16.0.5); / / 4
console.log(16** 0.5);         / / 4
let squared = 3; 
squared **= 2;
console.log(squared); / / 9
let sqrt = 16; 
sqrt **= 0.5; 
console.log(sqrt); / / 4
Copy the code

3.5.6 Additive operators

1. Add operator

The addition operator (+) is used to find the sum of two numbers. If both operands are numeric, the addition operator performs addition and returns the result according to the following rules:

  • NaN is returned if any of the operands is NaN;
  • If Infinity plus Infinity, Infinity is returned;
  • If it’s -infinity plus -infinity, it returns -infinity;
  • If Infinity plus -infinity, NaN is returned;
  • If it is +0 +0, it returns +0;
  • If it is -0 plus +0, +0 is returned;
  • If it’s -0 plus -0, it returns -0.

However, if one of the operands is a string, the following rule applies:

  • If both operands are strings, concatenate the second string to the first;
  • If only one operand is a string, the other operand is converted to a string and the two strings are concatenated.

If any of the operands are objects, values, or booleans, their toString() method is called to get the string, and the previous string rules apply. For undefined and null, the String() function is called to get “undefined” and “null”, respectively.

2. Subtraction operators

The subtraction operator (-) is also a frequently used operator.

  • If both operands are numeric, mathematical subtraction is performed and the result is returned.
  • NaN is returned if any of the operands is NaN.
  • If Infinity minus Infinity, NaN is returned.
  • If it is -infinity minus -infinity, NaN is returned.
  • If it’s Infinity minus -infinity, it returns Infinity.
  • If it’s -infinity minus Infinity, it returns -infinity.
  • If it’s +0 minus +0, it returns +0.
  • If it’s +0 minus -0, it returns -0.
  • If it’s -0 minus -0, it returns +0.
  • If any of the operands is a string, Boolean, null, or undefined, it is first converted to a numeric value behind the scenes using Number(), and then the math is performed according to the previous rules. If the result of the transformation is NaN, the result of the subtraction calculation is NaN.
  • If any of the operands is an object, the valueOf() method is called to get the value representing it. If the value is NaN, the result of the subtraction calculation is NaN. If the object does not have a valueOf() method, its toString() method is called and the resulting string is then converted to a value.

3.5.7 Relational operators

The relational operator performs the comparison of two values, including less than (<), greater than (>), less than or equal to (<=), and greater than or equal to (>=), as we learned in math class. Each of these operators returns a Boolean value.

  • If the operands are all numeric, a numeric comparison is performed.
  • If the operands are all strings, the encoding of the corresponding character in the string is compared one by one.
  • If any of the operands is a value, the other operand is converted to a value and a numeric comparison is performed.
  • If any of the operands are objects, the valueOf() method is called, and the comparison is performed according to the previous rules after the result is obtained. If there is no valueOf() operator, the toString() method is called and the comparison is performed according to the previous rules after the result is obtained.
  • If any of the operands is a Boolean, it is converted to a numeric value before the comparison is performed.

3.5.8 Equality operator

1. Equal and not equal

The ECMAScript equal operator is represented by two equals signs (==) and returns true if the operands are equal. The unequal operator uses an exclamation mark and an equal sign (! =) means that true is returned if the operands are not equal. Both operators perform a row type conversion (often called a cast) to determine whether the operands are equal.

  • If any of the operands is a Boolean, it is converted to a value and then compared for equality. False converts to 0 and true converts to 1.
  • If one of the operands is a string and the other is a value, it tries to convert the string to a value and then compares for equality.
  • If one operand is an object and the other is not, the valueOf() method of the object is called to get its original value, which is then compared according to the previous rules. When comparing, the two operators follow the following rules.
  • Null is equal to undefined.
  • Null and undefined cannot be converted to other types of values for comparison.
  • If any of the operands is NaN, the equality operator returns false and the inequality operator returns true. Remember: Even if both operands are NaN, the equality operator returns false because NaN is not equal to NaN by rule.
  • If both operands are objects, they are compared to see if they are the same object. The equality operator returns true if both operands refer to the same object. Otherwise, the two are not equal.

There are special cases

2. Congruence and incongruence

The congruence and incongruence operators are similar to the equality and inequality operators, except that they do not convert operands when comparing equality. The congruent operator is represented by three equals signs (===) and returns true only if the two operands are equal without conversion. Although null == undefined is true (because the two values are similar), null === undefined is false because they are not of the same data type.

3.5.9 Conditional operators

The conditional operator is one of the most versatile operators in ECMAScript, with the same syntax as in Java:

variable = boolean_expression ? true_value : false_value;

let max = (num1 > num2) ? num1 : num2; 
Copy the code

3.5.10 Assignment operator

Simple assignment is denoted by an equals sign (=), assigning the value of the right hand side to the variable on the left hand side, and compound assignment is denoted by a multiplicative, additive, or bitwise operator followed by an equals sign (=).

  • Multiply and assign (*=)
  • Assign after division (/=)
  • After modulo assignment (%=)
  • Assign (+=)
  • Assignment after subtraction (-=)
  • Assign after left shift (<<=)
  • Assign after right shift (>>=)
  • Assignment after unsigned right shift (>>>=)

These operators are simply shorthand syntax and using them does not improve performance.

3.5.11 Comma operator

The comma operator can be used to perform multiple operations in a single statement, or to aid in assignment. Using the comma operator to separate values during assignment eventually returns the next value in the expression

let num1 = 1, num2 = 2, num3 = 3; 
let num = (5.1.4.8.0); // the value of num is 0
Copy the code

3.6 the statement

3.6.1 track if statement

The if statement is one of the most frequently used statements and has the following syntax:

if (condition) statement1 else statement2 
Copy the code

3.6.2 do – while statement

A do-while statement is a post-test loop in which the exit condition is evaluated only after the code in the body of the loop executes. In other words, the code in the loop executes at least once.

do {   statement  } while (expression); 
Copy the code

3.6.3 while statement

A while statement is a test-loop statement that checks the exit condition before executing the code inside the loop. Therefore, it is possible that the code in the while loop body will not execute.

while(expression) statement 
Copy the code

3.6.4 radar echoes captured for statement

The for statement is also a test-first statement, but it adds initialization code before entering the loop and a table expression to execute after the loop is executed. The syntax is as follows

for (initialization; expression; post-loop-expression) statement
Copy the code

Initialization, conditional expressions, and post-loop expressions are not required. Thus, an infinite loop can be created by writing:

for (;;) { // infinite loop doSomething(); }
Copy the code

If only conditional expressions are included, then the for loop actually becomes the while loop:

let count = 10; 
let i = 0;
for (; i < count; ) { 
console.log(i); 
i++; 
} 
Copy the code

3.6.5 the for in statement

A for-in statement is a strict iteration statement that enumerates non-signed key attributes in an object. The syntax is as follows:

for (property in expression) statement 
Copy the code

If the for-in loop iterates over a variable that is null or undefined, the body of the loop is not executed

3.6.6 for – statement

A for-of statement is a strict iteration statement that iterates through the elements of an iterable. The syntax is as follows:

for (property of expression) statement 
// The for-in loop displays all attributes of the BOM object window.
// Each time the loop executes, the propName variable is assigned a window object property until all of the window properties are enumerated.
As with the for loop, const in the control statement is not required here. But to ensure that this local variable is not modified, const is recommended.
 
Copy the code

Here’s an example:

for (const el of [2.4.6.8]) {   document.write(el); } 
// the for-of statement displays all the elements in a 4-element array.
// The loop continues until all elements are iterated over.
As with the for loop, const in the control statement is not required here. But to ensure that this local variable is not modified, const is recommended
Copy the code

3.6.7 Label Statement

Label statements are used to label statements. The syntax is as follows: label: statement

start: for (let i = 0; i < count; i++) {   console.log(i);  } 
Copy the code

In this case, start is a label that can be referenced later with a break or continue statement.

3.6.8 Break and continue statements

The break and continue statements provide tighter control over the execution of loop code. The break statement is used to exit the loop immediately and force the next statement after the loop. The continue statement is also used to exit the loop immediately, but is executed again from the top of the loop.

let num = 0; 
 
outermost:  
for (let i = 0; i < 10; i++) { 
  for (let j = 0; j < 10; j++) { 
   if (i == 5 && j == 5) {      
     continueoutermost; } num++; }}console.log(num); / / 95
// When both I and j are equal to 5, continue is executed, which causes the inner loop to execute 5 fewer times, resulting in num equal to 95.
Copy the code

The 3.6.9 with statement

The with statement is used to set the code scope to a specific object. The syntax is:

with (expression) statement; 
Copy the code

With extends the scope chain, and strict mode does not allow the with statement, otherwise an error will be thrown.

3.6.10 switch statement

The switch statement is a flow-control statement closely related to the IF statement, borrowed from other languages. The switch statement in ECMAScript has a very similar syntax to the SWITCH statement in C, where each case (condition/branch) is equivalent to: “Execute the following statement if the expression is equal to the following value.” The break keyword causes code execution to jump out of the switch statement. If there is no break, the code continues to match the next condition. The default keyword is used to specify the statement to be executed by default (equivalent to the else statement) if none of the conditions are met.

switch (expression) { 
case value1:  
  statement   
  break;  
case value2:    
  statement    
  break;  
case value3:  
  statement  
  break;  
case value4: 
  statement   
  break;  
default:     
  statement 
}
Copy the code

3.7 the function

Functions are a core component of any language because they can encapsulate statements and execute them anywhere, at any time. Functions in ECMAScript are declared using the function keyword, followed by a set of parameters, followed by the function body.

function functionName(arg0, arg1,... ,argN) {  
  statements 
}
Copy the code

Strict mode also has some restrictions on functions:

  • Functions cannot be named eval or arguments;
  • Function arguments cannot be called eval or arguments;
  • Two named parameters cannot have the same name.

If you violate the above rules, syntax errors will result and the code will not execute.

3.8 summary

The core language features of JavaScript are defined in ECMA-262 in the form of the pseudo-language ECMAScript. ECMAScript contains all the basic syntax, operators, data types, and objects that perform basic computational tasks, but does not provide a mechanism for getting input and producing output. Understanding ECMAScript and its complex details is key to fully understanding JavaScript in a browser. Here’s a summary of the basic elements in ECMAScript.

  • Basic data types in ECMAScript include Undefined, Null, Boolean, Number, String, and Symbol.
  • Unlike other languages, ECMAScript does not distinguish between integer and floating point values, and has only one numeric data type, Number.
  • Object is a complex data type that is the base class for all objects in the language.
  • Strict patterns impose restrictions on certain error-prone parts of the language.
  • ECMAScript provides many of the basic operators found in C and C-like languages, including mathematical, Boolean, relational, equality, and assignment operators.
  • The flow control statements in this language are mostly borrowed from other languages, such as if statements, for statements, and switch statements. Functions in ECMAScript are different from functions in other languages.
  • There is no need to specify the return value of a function, because any function can return any value at any time.
  • Functions that do not specify a return value actually return the special value undefined.

References:

JavaScript Advanced Programming (Version 4)