ECMAScript has six simple data types (also known as primitive types) :
- Undefined
- Null
- Boolean
- Number
- String
- Symbol. Symbol is new to ECMAScript 6.
- Object.
1 typeof operator: returns the data typeof a variable
const name = "t-mac";
console.log(typeof name)
Copy the code
- “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.
Calling typeof NULL returns “object”. This is because the special value null is considered a reference to an empty object.
Strictly speaking, functions are considered objects in ECMAScript and do not represent a data type. However, functions have their own special properties. To do this, it is necessary to distinguish functions from other objects through the Typeof operator.
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:
let name;
console.log(typeof name) // undefined
console.log(name == undefined) // true
Copy the code
The variable name is not initialized when it is declared. When you compare it to the literal of undefined, they are equal
In general, you should never explicitly set undefined to a variable. The literal undefined is mainly used for comparison and did not exist prior to ecMA-262 version 3. The purpose of adding this special value is to formalize the difference between a null object pointer and an uninitialized variable.
Note the difference between declaring an uninitialized variable and an undeclared variable
let name;
console.log(typeof name) // undefined
console.log(age) // ReferenceError: age is not defined
Copy the code
But what if typeof is used for an undeclared variable?
let name;
console.log(typeof name) // undefined
console.log(typeof age) // undefined
Copy the code
Calling typeof on an uninitialized variable returns “undefined”, but calling it on an undeclared variable returns “undefined”
let name;
console.log(typeof name) // undefined
if(name){
console.log("Hello !!!!")}if(! name){console.log("hello !!!! ")}Copy the code
Chinese “hello !!!!” It won’t print, it will print “hello!!!! “
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 name = null;
console.log(name == null) // true
console.log(typeof name) // object
// Typeof returns a value of type string
console.log(typeof(typeof name)) // string
Copy the code
Undefined values are derived from null values, so ECMA-262 defines them as ostensibly equal:
console.log(null= =undefined) //true
Copy the code
Comparing null and undefined with the equal operator (==) always returns true. Note, however, that this operator converts its operands for comparison purposes
4 a 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.
let found = true;
let lost = false;
Copy the code
Although there are only two Booleans, all other ECMAScript type values have corresponding Boolean equivalents. To convert a value of another type to a Boolean, call the special Boolean() transformation function:
console.log(Boolean("")); // false
console.log(Boolean("xxxxx")); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean(-1)); // true
Copy the code
-
Null and undefined return false
-
The empty string returns false, the rest true
-
Numeric type, not equal to 0 returns true, 0 returns false
See here to understand why the above two if statements are printed in English hello
Number 5 types
The Number type uses IEEE 754 format to represent integer and floating point values (also called double values in some languages).
5.1 8, 10, and 16 indicate
- decimal
let intNum = 55; //10jinzhi
Copy the code
- Base 8: For octal literals, the first digit must be zero (0), followed by the corresponding octal digit (values 0 to 7)
let octalNum1 = 070; // octal 56
let octalNum2 = 079; // Invalid octal value, treated as 79
let octalNum3 = 08; // Invalid octal value, treated as 8
Copy the code
Octal literals are invalid in strict mode, causing JavaScript engines to throw syntactic errors: octal values in ECMAScript 2015 or ES6 are represented with the 0O prefix; In strict mode, the prefix 0 is considered a syntax error, and 0o should be used to represent octal values.
- Hexadecimal: To create a hexadecimal literal, you must prefix the real numeric value with 0x (case sensitive), followed by the hexadecimal number (0)
9 and AF)
let hexNum1 = 0xA; // Hexadecimal 10
let hexNum2 = 0x1f; // Hexadecimal 3
Copy the code
5.2 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.
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 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.
let floatNum = 3.125 e7; / / equal to 31250000
Copy the code
Floating-point values are accurate to up to 17 decimal places, but are 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.
5.3 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, which in most browsers is 5E-324;
-
The maximum value that can be expressed 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.
To determine if a value isFinite(that is, between the minimum and maximum that JavaScript can represent), use the isFinite() function,
let result = Number.MAX_VALUE + Number.MAX_VALUE;
console.log(isFinite(result)); // false
Copy the code
5.4 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
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:
- Any operation involving NaN always returns NaN (e.g. NaN/10)
- NaN is not equal to any value including NaN
console.log(NaN= =NaN); // false
Copy the code
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.”
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
5.5 Numeric conversion: Number(), parseInt() and parseFloat()
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.
5.5.1 Number ()
The Number() function performs the conversion based on the following rule:
- Boolean: True to 1, false to 0
- Number type: Returned directly
- Null: Returns 0
- Underfind: Returns NaN
- String: convert to a number (including 8 hexadecimal) if it can, otherwise return NaN; An empty string returns 0
- Object type, its valueOf() method is called first, and if valueOf returns a NaN result, its toString method is called, which is converted according toString rules.
let num1 = Number("Hello world!"); // NaN
let num2 = Number(""); / / 0
let num3 = Number("000011"); / / 11
let num4 = Number(true); / / 1
let num5 = console.log(Number("0x7")) / / 7
let num6 = console.log(Number("")) // 0 An empty string returns 0
Copy the code
5.5.2 parseInt () and parseFloat ()
The parseInt() function focuses more on whether the string contains a numeric pattern.
-
The first space in the string is ignored, and the first non-space character is converted. 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, octal, 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.
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 you know that the value to be parsed is hexadecimal, you can pass 16 as the second argument to parse correctly:
let num = parseInt("0xAF".16); / / 175
let num1 = parseInt("10".2); // 2
let num2 = parseInt("10".8); // 8
let num3 = parseInt("10".10); // 10, in decimal notation
let num4 = parseInt("10".16); // 16 is resolved in hexadecimal format
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
6 type String
The String data type represents a sequence of zero or more 16-bit Unicode characters. Strings can be marked with double (“), single (‘), or backquotes
let s1 = "kobe";
let s2 = 'tttt';
let s3 = `ssdsad`;
console.log(s1,s2,s3);
Copy the code
6.1 Character literals
String data types contain character literals that represent non-print characters or characters that have other uses
\n newline \ T TAB character \b Backspace \ R enter \ F page feed \ backslash (\) \'single quotes \' double quotes \ 'back quotesCopy the code
6.2 Character String Characteristics
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 into the variable,
let lang = "Java";
lang = lang + "Script";
Copy the code
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”. Finally, the original string “Java” and string “Script” are destroyed, because neither string is used anymore.
6.3 Converting to a String
toString()
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
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 parameters, you can get a string representation of the numeric value in binary, octal, hexadecimal, or any other valid base
let num = 10;
console.log(num.toString()); 10 "/ /"
console.log(num.toString(2)); // "1010" is binary
Copy the code
String()
The String() function always returns a String representing the value of the corresponding type. The String() function follows the following rules:
- Call toString’s no-argument method first;
- If toString returns NULL, “null” is returned;
- If undefined, return undefined
let value1 = 10;
let value2 = true;
let value3 = null;
let value4;
console.log(String(value1)); 10 "/ /"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
Copy the code
The result of converting numeric and Boolean values is the same as that of calling toString(). Because null and undefined have no toString() methods, the String() method returns literal text for both values.
+ “”
The plus operator with an empty string can also be converted to a string;
6.4 Template literals
ECMAScript 6 adds the ability to define strings using template literals. Instead of using single or double quotes, template literals retain newline characters and can define strings across lines
<script>
let myMultiLineString = 'first line\nsecond line';
let myMultiLineStringTemplate = `first line
second line`;
console.log(myMultiLineString);
console.log("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
console.log(myMultiLineStringTemplate);
</script>
Copy the code
Output:
first line
second line
---------------------------
first line
second line
Copy the code
6.5 String Interpolation
One of the most commonly used features 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. Template literals are immediately evaluated and converted to string instances upon definition, and any inserted variables are also evaluated from their nearest scope.
String interpolation is implemented by using a JavaScript expression in ${}
Getting started: String concatenation
let a = 5;
let s = a + ` times ` + a + ` = ` + a * a;
console.log(s);
let s2 = `${a}Multiplied by the${a} = ${a * a}`;
console.log(s2);
Copy the code
The final output is always: 5 times 5 = 25
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; toString() is called when an expression is converted to a string
Functions and methods can be called in interpolation expressions:
let name = "kobe";
// Kobe is big
console.log(`${name}Capital:${name.toUpperCase()}`);
Copy the code
7 Symbol types
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. It sounds similar to private properties, but symbols are not added to provide the behavior of private properties (especially because the Object API provides methods to 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.
7.1 Symbol type initialization
- 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
// Use "foo", but the two symbol types are not equal, are completely unrelated variables
console.log(fooSymbol == otherFooSymbol); // false
Copy the code
- Symbols don’t have literal syntax, which is what makes them useful. According to the specification, you can guarantee that it will not overwrite existing object attributes, either symbolic or string, by simply creating an instance of Symbol() and using it as a new attribute of the object.
let genericSymbol = Symbol(a);console.log(genericSymbol); // Symbol()
let fooSymbol = Symbol("foo");
console.log(fooSymbol); // Symbol(foo);
Copy the code
- 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
Copy the code
- 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
7.2 Using 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.
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 fooGlobalSymbol1 = Symbol.for("foo");
console.log(typeof fooGlobalSymbol1); // symbol
let fooGlobalSymbol2 = Symbol.for("foo");
// This returns true because it is the same symbol instance
console.log(fooGlobalSymbol1 == fooGlobalSymbol2) // true
Copy the code
However, symbols defined in the global registry are not the same as symbols defined using Symbol(), even if the same Symbol description is used:
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.
Symbol.keyfor () to query the global registry. This method accepts the Symbol and returns the string key corresponding to the global Symbol. If the query is not global, undefined is returned.
// Register global symbols
let fooGlobalSymbol1 = Symbol.for("foo");
let fooGlobalSymbol2 = Symbol.for("foo");
console.log(Symbol.keyFor(fooGlobalSymbol1)); // foo
console.log(Symbol.keyFor(fooGlobalSymbol2)); // foo
// Common symbols
let symbol3 = Symbol("foo");
console.log(Symbol.keyFor(symbol3)); // undefined
Copy the code
7.3 Using symbols as Attributes
Wherever you can use strings or values as attributes, you can use symbols.
let s1 = Symbol("foo");
// o This object defines a property Symbol(foo) with a value of "foo val"
let o = {
[s1]: "foo val"};console.log(o); // {Symbol(foo): "foo val"}
Copy the code
It could also go like this:
let s1 = Symbol("foo");
let o = {
[s1]: "foo val"};let s2 = Symbol("bar");
// define a Symbol(bar) property with the value "bar val".
Object.defineProperty(o, s2, { value: "bar val" });
// {Symbol(foo): "foo val", Symbol(bar): "bar val"}
console.log(o);
Copy the code
You can also:
let s1 = Symbol("foo");
let o = {
[s1]: "foo val"};let s2 = Symbol("bar");
// define a Symbol(bar) property with the value "bar val".
Object.defineProperty(o, s2, { value: "bar val" });
let s3 = Symbol("baz");
let s4 = Symbol("qux");
Object.defineProperties(o, {
[s3]: { value: "baz val" },
[s4]: { value: "qux val"}});// {Symbol(foo): "foo val", Symbol(bar): "bar val", Symbol(baz): "baz val", Symbol(qux): "qux val"}
console.log(o);
Copy the code
7.4 access Object properties: Object. GetOwnPropertyNames () and the Object. GetOwnPropertySymbols ()
- Object. GetOwnPropertyNames () returns an Object instance of conventional attributes array,
- Object. GetOwnPropertySymbols array of symbols () returns an Object instance attributes
Object. GetOwnPropertyNames () and the Object. GetOwnPropertySymbols () these two methods the return value of mutually exclusive to each other.
-
Object. GetOwnPropertyDescriptors () will return to contain both conventional and symbolic attributes descriptor Object
-
Reflect.ownkeys () returns two types of keys
// Define a symbol
let ageSymbol = Symbol("age")
let person = {
[ageSymbol] : 43.// Symbolic attributes
name: "kobe" // General attributes
}
// {name: "kobe", Symbol(age): 43}
console.log(person)
// getOwnPropertyNames => ["name"]
console.log("getOwnPropertyNames => ".Object.getOwnPropertyNames(person))
// getOwnPropertySymbols => [Symbol(age)]
console.log("getOwnPropertySymbols => ".Object.getOwnPropertySymbols(person))
console.log(Reflect.ownKeys(person));
Copy the code
7.5 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.
For example, if we know that a for-of loop (Java’s enhanced for) 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.
const products = ['oranges'.'apples'];
for (const product of products) {
console.log(product);
}
Copy the code
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.
7.6 Symbol. AsyncIterator
This symbol represents, as a property, “a method that returns the object’s default AsyncIterator.” Used by the for-await-of statement. This symbol represents the function that implements the asynchronous iterator API.
The for-await-of loop uses this function to perform asynchronous iterations. As they loop, they call a function with Symbol. AsyncIterator as the key and expect that function to return an object that implements the iterator API. Many times, the object returned is an AsyncGenerator that implements the API
class Foo {
async* [Symbol.asyncIterator]() {}
}
let f = new Foo();
let temp = f[Symbol.asyncIterator];
console.log(typeof temp); // functioon
console.log(temp);
Copy the code
The object generated by the symbol.asynciterator function should continuously return Promise instances through its next() method. It can be returned either explicitly by calling the next() method or implicitly by an asynchronous generator function:
class Emitter {
constructor(max) {
this.max = max;
this.asyncIdx = 0;
}
async* [Symbol.asyncIterator]() {
while (this.asyncIdx < this.max) {
yield new Promise((resove) = > resove(this.asyncIdx++)); }}}async function asyncCount() {
let emitter = new Emitter(5);
for await (const x of emitter) {
console.log(x);
}
}
asyncCount();
Copy the code
7.7 Symbol. HasInstance
This symbol represents, as a property, “a method that determines whether a constructor object recognizes an object as an instance of it. Used by the instanceof operator. The instanceof operator can be used to determine whether an object instance has an archetype on its archetype chain
function Foo() {}
let f = new Foo();
console.log(f instanceof Foo); // true
Copy the code
In ES6, the instanceof operator uses the symbol.hasinstance function to determine the relationship. The function with symbol.hasinstance as the key performs the same operation, but the operands are switched
function Foo() {}
let f = new Foo();
console.log(Foo[Symbol.hasInstance](f));
Copy the code
This property is defined on the prototype of Function, so it is called by default on all functions and classes. Because the Instanceof operator looks for this property definition on the stereotype chain just as it would any other property on the stereotype chain, this function can be redefined statically on an inherited class
class Bar {}
class Baz extends Bar {
static [Symbol.hasInstance]() {
return false; }}let b = new Baz();
console.log(Bar[Symbol.hasInstance](b)); // true
console.log(b instanceof Bar); // true
// Baz overwrites hasInstance, so returns false
console.log(Baz[Symbol.hasInstance](b)); // false
console.log(b instanceof Baz); // false
Copy the code
7.8 Symbol. IsConcatSpreadable
This symbol, as an attribute, means “a Boolean value that, if true, means the object should have its Array elements flattened with array.prototype.concat ()”.
The array.prototype.concat () method in ES6 selects how to concatenate an array-like object into an Array instance based on the type of object it receives. Cover Symbol isConcatSpreadable values can modify this behavior.
Array objects are flattened to an existing array by default, and false or false values cause the entire object to be appended to the end of the array. An array-like object is appended to the end of the array by default, and a true or true value causes the array-like object to be flattened to the array instance. Other than an array object in the Symbol. IsConcatSpreadable is set to true in the case will be ignored.
Plain array:
let initial = ["foo"];
let array = ["bar"."car"];
// The isConcatSpreadable property of the array is undefined
console.log(array[Symbol.isConcatSpreadable]); // undefinded
The concat() method is used to join two or more arrays.
// It is flattened to an existing array by default
// We append each element of the array
// The number of elements in the merged array is 3
console.log(initial.concat(array)); // ['foo', 'bar', 'car']
// False or false values cause the entire object to be appended to the end of the array. Array-like objects are appended to the end of the array by default,
array[Symbol.isConcatSpreadable] = false;
// Append the array object to the second element of the merged array
console.log(initial.concat(array)); // ['foo', Array(2)]
// True or true causes the array-like object to be flattened to the array instance
array[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(array)); // ['foo', 'bar', 'car']
Copy the code
Class array: Note the difference between the following and the above:
let initial = ["foo"];
// This is an object array
let array = { 0: "bar" ,1:"car".length: 2};
// The isConcatSpreadable property of the array is undefined
console.log(array[Symbol.isConcatSpreadable]); // undefinded
The concat() method is used to join two or more arrays.
// False or false values are flattened to the existing array
// array will be merged as a whole
console.log(initial.concat(array)); // ['foo', {...}]
array[Symbol.isConcatSpreadable] = false;
// Append the array object to the second element of the merged array
console.log(initial.concat(array)); // ['foo', {...}]
// True or true causes the array-like object to be flattened to the array instance
// Add bar and car in array one by one
array[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(array)); // ['foo', 'bar', 'car']
Copy the code
** Other types: **
let otherObject = new Set().add('qux');
console.log(otherObject[Symbol.isConcatSpreadable]); // undefined
// Is appended to the end of the array by default
console.log(initial.concat(otherObject)); // ['foo', Set(1)]
/ / not class array object object in other Symbol. IsConcatSpreadable is set to true in the case will be ignored.
otherObject[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(otherObject)); // ['foo']
Copy the code
7.9 Symbol. The iterator
This symbol represents, as a property, “a method that returns the default iterator for an object. Used by for-of statement
This symbol represents the function that implements the iterator API.
Language constructs such as for-of loops use this function to perform iterative operations. As they loop, they call a function with symbol. iterator as the key, which by default returns an object implementing the iterator API. In many cases, the object returned is a Generator that implements the API:
class Foo {
*[Symbol.iterator]() {}
}
let f = new Foo();
console.log(f[Symbol.iterator]()); // Generator {<suspended>}
Copy the code
The object generated by the symbol.iterator function should return values successively through its next() method. It can be returned either explicitly by calling the next() method or implicitly by a generator function
7.10 Symbol. The match
This symbol represents, as a property, “a regular expression method that uses regular expressions to match strings. Used by the string.prototype.match () method”
The string.prototype.match () method evaluates regular expressions using functions with symbol.match as keys. This function is defined by default on the prototype of the regular expression, so all instances of the regular expression are valid arguments to the String method by default:
ƒ [Symbol. Match]() {[native code]}
console.log(RegExp.prototype[Symbol.match]);
// "bar", index: 3, input: "foobar", groups: undefined]
console.log('foobar'.match(/bar/));
Copy the code
Passing a non-regular expression value to this method causes the value to be converted to a RegExp object. If you want to change this behavior so that the method uses parameters directly, you can redefine the symbol.match function to replace the default behavior of evaluating regular expressions, so that the match() method uses instances of non-regular expressions.
The symbol.match function takes one argument, which is an instance of the string that calls the match() method. There is no limit to the value returned
class FooMatcher {
static [Symbol.match](target) {
return target.includes('foo'); }}console.log('foobar'.match(FooMatcher)); // true
console.log('barbaz'.match(FooMatcher)); // false
class StringMatcher {
constructor(str) {
this.str = str;
}
[Symbol.match](target) {
return target.includes(this.str); }}console.log('foobar'.match(new StringMatcher('foo'))); // true
console.log('barbaz'.match(new StringMatcher('qux'))); // false
Copy the code
7.11 Symbol. The replace
This symbol represents, as a property, “a regular expression method that replaces matched substrings in a string. Used by the string.prototype.replace () method “. The string.prototype.replace () method evaluates regular expressions using functions with symbol.replace as keys. This function is defined by default on the prototype of the regular expression, so all instances of the regular expression are valid arguments to the String method by default:
console.log(RegExp.prototype[Symbol.replace]);
// f [Symbol.replace]() { [native code] }
console.log('foobarbaz'.replace(/bar/.'qux'));
// 'fooquxbaz'
Copy the code
8 the 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);Copy the code
This syntax is similar to Java, but ECMAScript only requires that parentheses be used when supplying arguments to constructors. If there are no arguments, as in the example above, then you can omit the parentheses entirely (not recommended) :
let o = new Object; // It is valid for ** but not recommended
Copy the code
An instance of Object by itself is not very useful, but it is important to understand the concepts associated with it. Like java.lang.Object in Java, Object in ECMAScript is the base class from which other objects are derived. All properties and methods of type Object also exist on derived objects.
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.
-
PropertyIsEnumerable (propertyName) : A for-in statement enumeration used to determine if a given property can be used. 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().
Object is the base class of all objects in ECMAScript, so any Object has these properties and methods.
The behavior of objects in ECMA-262 does not necessarily apply to other objects in JavaScript. For example, BOM and DOM objects in the browser environment are host objects defined and provided by the host environment. Host objects are not bound by ECMA-262, so they may or may not inherit Object.