The data type

There are seven JavaScript data types.

Six simple types: Undefined, Null, Boolean, Number, String, Symbol

One complex type: Object

BigInt and function are controversial, treated as new data types in some places and as special objects in others.

The typeof operator

The typeof operator can return the data typeof a variable. It can return 7:

  • “Undefined” means undefined;
  • “Boolean” means Boolean;
  • “String” means string;
  • “Number” means number;
  • “Symbol” means symbol;
  • “Object” indicates the value object or NULL.
  • “Function” means the value is a function;

Null is recognized as object because it is considered an empty object.

Undefined

Undefined has only one value, which is the special value Undefined. It was added to formalize the difference between Null and uninitialized variables.

When a var or let declares a variable without giving it an initial value, its value is undefined.

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

Uninitialized variables also return undefined.

// age is not declared
console.log(age); // also undefined, only error
Copy the code

But undefined is not the same thing.

Use it as a judgment condition:

let message;

if (message) {
  // This will not be executed soon
}

if(! message) {// This will be executed soon
}

// Do not declare age
if (age) {
  // Get an error
}
Copy the code

Null

The word is pronounced [nʌl].

The null type has only one value, NULL, representing an empty object pointer.

When declaring a variable, it is best to initialize it. If you really don’t know what value to assign in the first place, NULL is a good choice.

Ecma-262 considers NULL and defined to be ostensibly equal

Because undefined is derived from null. So using == returns true.

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

Null is false

So it’s the same as undefined.

let message = null;

if (message) {
  // Will not be executed
}
if(! message) {/ /
}
Copy the code

Boolean

Boolean has two literals: true and false. These two Booleans are different from numbers: true does not equal 1 and false does not equal 0.

True and false must be lowercase. True and False are the other two identifiers.

All ECMAScript values have Boolean equivalents. Use Boolean() to convert.

let messageBoolean = Boolean("How are you!");
Copy the code

Rules for converting different types of values to Booleans:

The data type Conversion to true Conversion to false
String Non-empty string An empty string
Number Non-zero values (including infinity) 0, NaN
Object Any object null
Undefined N/A (non-existent) undefined

When we use if (message) judgment, the judgment condition message is converted to the corresponding Boolean value. So it’s important to remember this chart.

Number

The Number type uses IEEE 754 format to represent integers and floating point numbers.

Decimal integer

The most basic is the decimal integer.

Octal literals

The first digit in octal must be 0, followed by the corresponding octal digit (values 0-7). If a number is out of range, it is recognized as decimal.

let num1 = 070; // octal 56
let num2 = 079; // 79 in decimal
Copy the code

Octal literals are invalid in strict mode, causing JavaScript engines to report errors.

Hexadecimal literal

The first two digits of hexadecimal must be 0x, followed by hexadecimal digits (values 0-9 and A-f). Both upper and lower case are acceptable.

let num = 0xa; // hexadecimal 10
Copy the code

Floating point value

Defines that a floating-point value must contain a decimal point and must have at least one digit after the decimal point.

let num = 1.1;
let num2 = 0.1; // Valid, but not recommended
Copy the code

Storing floating-point values uses twice as much memory as integer values, so ECMAScript always wants to convert values to integers.

When there are no digits or only zeros after the decimal point, the value becomes an integer.

Floating-point scientific notation

Floating-point values can be expressed in scientific notation for very large or very small values.

let num = 3.125 e7; / / 31250000
Copy the code

Use an uppercase or lowercase e, plus a number such as 7, to represent 10 to the seventh power.

10 to the minus something we add the – sign:

let num = 3125e-3; / / 3.125
Copy the code

ECMAScript converts floating point numbers with at least six zeros after the decimal point to scientific notation by default. (for example, 0.000 000 3) is converted to 3E-7.

  • Floating-point accuracy is 17 decimal places

Errors can occur in floating-point calculations

For example, 0.1 plus 0.2 equals 0.300 000 000 000 000 04 instead of 0.3.

Be very careful in this particular case.

This problem occurs because of IEEE 754. Any language that uses this format has this problem.

Number Specifies the range of values

Due to memory limitations, ECMAScript values have upper and lower limits.

The minimum value is stored in number.min_value, which in most browsers is 5E-324.

The maximum value is stored in number.max_value, which in most browsers is 1.797 693 134 862 315 7e+30.

When the value is out of range, a value that is too large is converted to a special Infinity, and a value that is too small is -infinity. Infinity and -infinity cannot be evaluated; they have no numerical representation available for evaluation.

To determine if a number is infinite, use isFinite().

let num = Number.MAX_VALUE;
console.log(isFinite(num)); //true
Copy the code

NEGATIVE_INFINITY and POSITIVE_INFINITY can also be used to get positive and negative Infinity. These two properties contain the values -infinity and Infinity, respectively.

In division, if the numerator is non-zero and the denominator is 0 or -0, Infinity or -infinity is returned:

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

NaN

It’s a special Number, and typeof returns a Number. But what he meant was “not a number.”

It occurs when the operation that was supposed to return a numeric value fails and returns without throwing an error.

For example, 0 divided by anything would be wrong, so NaN would be returned.

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

In ECMAScript, +0 and -0, in addition to 0, are nans for any number.

The characteristics of NaN

  1. Any operation that involves NaN always returns NaN. (such as NaN / 10)
  2. NaN is not equal to any value, including itself.
console.log(NaN= =NaN); // false
Copy the code

isNaN()

IsNaN () can determine if a parameter is “not a number.” One problem, however, is that it converts any type of data to a numeric value first (following the rules of the Number() function), so anything that cannot be converted is recognized as NaN and returns true.

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

Numerical transformation

Number()

The Number() function must begin with a capital letter N. It first determines the type of the parameter and converts it according to the following rules:

  1. Undefined: returns NaN

  2. Null: Returns 0

  3. Boolean values: true is 1, false is 0

  4. Value: Returns directly

  5. String:

    An empty string (no characters) returns 0.

    Valid integer characters, including plus and minus signs, are converted to decimal values.

    A valid floating-point value format such as “1.1” is converted to the corresponding floating-point value.

    Valid hexadecimal formats such as “0xf” are converted to the corresponding decimal integer value.

    If the string contains characters other than the above, NaN is returned.

  6. Object: Call the valueOf() method and convert 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.

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

parseInt()

The rules for parseInt() are simple:

  1. Ignore whitespace up to the first non-whitespace character. NaN is returned if it is not a value, +, -.

  2. Stop conversion when special characters are encountered and return the result.

  3. If the string starts with “0x”, it is interpreted as a hexadecimal integer.

  4. 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(""); // NaN
let num2 = parseInt("1234blue"); / / 1234
let num3 = parseInt("A"); // NaN
let num4 = parseInt("1.1"); / / 1
let num5 = parseInt("0xA"); // 10, interpreted as a hexadecimal integer
let num6 = parseInt(22.5); / / 22
let num7 = parseInt("70"); // 70 is interpreted as a decimal value
let num8 = parseInt("0xf"); // 15, interpreted as a hexadecimal integer
let num9 = parseInt(true); //NaN, cannot recognize Boolean values
Copy the code

So it only gets integers, and you can use it to round.

To prevent confusion, parseInt() can also pass in a second argument that specifies the base. You end up with decimal numbers.

let num1 = parseInt("0xAF".16); / / 175
let num2 = parseInt("AF".16); // 175, we can omit the 0x from the base
let num3 = parseInt("AF"); // NaN, do not pass that must be an error

let num4 = parseInt("10".2); // 2
let num5 = parseInt("10".8); // 8
let num6 = parseInt("10".10); // 10, in decimal notation
let num7 = parseInt("10".16); // 16 is resolved in hexadecimal format
Copy the code

It is recommended to always pass in the second parameter

parseFloat()

ParseFloat () also checks from scratch and stops when invalid characters are detected.

But it allows the decimal point to occur once. That is, it can return floating point numbers. And it only parses decimal numbers. So hexadecimal, because it starts with a 0, always gets a 0. It also has no second argument.

let num1 = parseFloat("1234blue"); // 1234, parsed as an integer
let num2 = parseFloat("0xA"); / / 0
let num3 = parseFloat("a"); //NaN
let num4 = parseFloat("22.5"); / / 22.5
let num5 = parseFloat("22.34.5"); / / 22.34
let num6 = parseFloat("0908.5"); / / 908.5
let num7 = parseFloat("3.125 e7"); / / 31250000
let num8 = parseInt(true); //NaN, cannot recognize Boolean values
Copy the code

String

A string represents zero or more sequences of 16-bit Unicode characters.

You can use double quotation marks, single quotation marks, and backquotation marks. In some languages, different quotation marks have different effects. But for ECMAScript, it’s all the same:

let name1 = "Mike";
let name2 = "Mike";
let name3 = `Mike`;
Copy the code

Once a string is created, it cannot be modified. By immutable, I do not mean that it cannot be concatenated:

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

Instead, the process in memory first creates a new 10-character space to hold “JavaScript”, then destroys the current “Java” and “Script”, and then gives the value “JavaScript” to Lang. So early concatenation strings were very slow. Today’s browsers address this problem specifically.

Character literals – special characters that can be recognized

literal meaning
\n A newline
\t TAB
\b backspace
\r enter
\f Change the page
\ \ The backslash |
\ ‘ Internal use of single-quoted strings, such as ‘He said, ‘hey.’
\” Same as above
\ ` Same as above
\xnn A hexadecimal character denoted by nn (where n is the hexadecimal number 0 to F), for example \x41 equals “A”
\unnnn Unicode characters in hexadecimal encoding NNNN (where n is the hexadecimal digits 0 to F), such as \ u03A3 equals the Greek character “σ”

Even if the escape character is long, it only counts as one character.

Let text = “This is the letter sigma: \ u03A3.”; The length of the escape sequence is 28, even if it contains a 6-length escape sequence.

Template literals

Template literals are quoted in backquotes.

Read the string in format

Template literals retain newline characters and recognize cross-line assignments.

let myMultiLineString = "first line\nsecond line";
console.log(myMultiLineString);
// first line
// second line"

let myMultiLineTemplateLiteral = `first line
second line`;
console.log(myMultiLineTemplateLiteral);
// first line
// second line

// The two ways are equivalent
console.log(myMultiLineString === myMultiLinetemplateLiteral); // true
Copy the code

Use template literals to pay attention to indentation:

let myTemplateLiteral = `first line
second line`;
console.log(myTemplateLiteral.length);
// output: 47. Because the first line is followed by 25 Spaces

let secondTemplateLiteral = `
first line
second line`;
console.log(secondTemplateLiteral[0= = ="\n");
// output: true. Because the template literal begins with a newline character
Copy the code

String interpolation

Template literals support string interpolation. That is, you can insert other strings into one string, also known as string formatting.

Using it requires the ${} format, with all inserted values being cast to strings by toString(). :

let value = 5;
let exponent = "second";
let interpolatedTemplateLiteral = `${value} to the ${exponent} power is ${ value * value }`;
Copy the code

You can insert functions

function capitalize(word) {
  return `${word[0].toUpperCase()}${word.slice(1)}`;
}
console.log(`${capitalize("hello")}.${capitalize("world")}! `); // Hello, World!
Copy the code

You can insert the current value

let value = "";
function append() {
  value = `${value}abc`;
  console.log(value);
}
append(); // abc
append(); // abcabc
append(); // abcabcabc
Copy the code

Support for defining tag functions

Template literals support defining tag functions and custom interpolation behavior.

The label function receives the template separated by the interpolation notation and the result of evaluating each expression. The tag function itself is a general function that applies custom behavior by prefixing to template literals, as shown in the following example. The arguments received by the label function are, in turn, the raw array of strings and the result of evaluation of each expression. The return value of this function is the string that evaluates the template literal.

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

Because the number of expression arguments is variable, you should usually collect them into an array using the rest operators:

let a = 6;
let b = 9;
function simpleTag(strings, ... expressions) {
  console.log(strings);
  for (const expression of expressions) {
    console.log(expression);
  }
  return "foobar";
}
let taggedResult = simpleTag`${a} + ${b} = ${a + b}`;
// ["", "+ "," = ", "]
/ / 6
/ / 9
/ / 15
console.log(taggedResult); // "foobar"
Copy the code

For template literals with n interpolations, the number of expression arguments passed to the tag function is always N, and the number of strings in the first argument passed to the tag function is always N +1. So, if you want to concatenate these strings with the result of evaluating the expression as the default returned string, you can do this:

let a = 6;
let b = 9;
function zipTag(strings, ... expressions) {
  return (
    strings[0] + expressions.map((e, i) = > `${e}${strings[i + 1]}`).join("")); }let taggedResult = zipTag`${a} + ${b} = ${a + b}`;

console.log(taggedResult); // "6 + 9 = 15"
Copy the code

Raw string

For some special values, we can use String.raw if we don’t want them to be recognized.

/ / 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 are not converted to escape sequences
console.log(String.raw`first line
second line`);
// first line
// second line
Copy the code

We can also retrieve the raw content of each string using the first argument of the label function, the.raw property of the string array:

function printRaw(strings) {
  for (const string of strings) {
    console.log(string);
  }
  for (const rawString of strings.raw) {
    console.log(rawString);
  }
}
printRaw`\u00A9The ${"and"}\n`;
/ / ©
// (newline)
// \u00A9
// \n
Copy the code

Convert to string

.toString()

Null and undefined cannot use this method.

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

For values, you can specify how many bases to convert to:

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

String()

String() is an enhanced version of.toString(). Return “null” and “undefined” for null and undefined.

console.log(String(null)); // "null"

let mess;
console.log(String(mess)); // "undefined"

console.log(String(mess1)); // undeclared undefined, get ReferenceError
Copy the code

String Length String.length

Intercept string

String.prototype.slice()

Accepts two index parameters: start and end.

If the end is not passed in, the end is truncated by default.

const str = "The quick brown fox jumps over the lazy dog.";

console.log(str.slice(31));
// expected output: "the lazy dog."

console.log(str.slice(4.19));
// expected output: "quick brown fox"

console.log(str.slice(-4));
// expected output: "dog."

console.log(str.slice(-9, -5));
// expected output: "lazy"
Copy the code

String.prototype.substring()

Similar to slice(). But negative arguments are recognized as 0 directly

String.prototype.substr()

Takes two arguments: start, and the number of strings to return

If the second argument is not passed in, the end is truncated by default. When the second argument exceeds the length of the string, it is truncated by default.

const str = 'The quick brown fox jumps over the lazy dog.';

console.log(str.substr(0.8);
// output: "The quic"

console.log(str.substr(-5.8);
// output: " dog."

console.log(str.substr(0.50);
// output: "The quick brown fox jumps over the lazy dog."

console.log(str.substr(4);
// output: "quick brown fox jumps over the lazy dog."
Copy the code

Symbol

Symbol is a new data type for ECMAScript6. Typeof returns symbol.

Symbol instances are unique and immutable. Its purpose is to ensure that object attributes use unique identifiers and there is no risk of attribute conflicts.

Symbols are used to create unique tokens that can then be used as non-string object attributes.

Symbols don’t have literal syntax, which is what makes them useful. By creating an instance of Symbol() and using it as a new attribute of the object, you are guaranteed that it will not overwrite existing object attributes, either symbols or strings.

Creating a normal symbol

The method for creating symbols uses the Symbol() function. Create a common symbol:

let sym = Symbol(a);Copy the code

Symbol instances are unique and created independently and they are not the same:

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

You can also pass in a string argument as a description of the symbol. You can use this string to debug your code in the future.

let fooSymbol = Symbol("foo");
Copy the code

However, this string argument has nothing to do with symbol definition or identity at all:

let fooSymbol = Symbol("foo");
let otherFooSymbol = Symbol("foo");

console.log(fooSymbol); // Symbol(foo);
console.log(otherFooSymbol); // Symbol(foo);
console.log(fooSymbol == otherFooSymbol); // false
Copy the code

Creating global symbols

Global functions require symbol.for ().

let sym = Symbol.for("apple");
Copy the code

To share and reuse symbol instances, you can create and reuse symbols in the global symbol registry by using a string as the key above.

The resulting two symbols are equivalent:

let fooGlobalSymbol = Symbol.for("foo"); // Create a new symbol
let otherFooGlobalSymbol = Symbol.for("foo"); // Reuse existing symbols

console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true
Copy the code

Symbol.for() performs an idempotent operation on each string key. When called, it checks the global registry, and if it doesn’t exist, a new symbol instance is generated and added to the registry. If so, an instance of the symbol is returned.

You must use symbol.for () to create and retrieve, otherwise an error will be reported as follows:

let localSymbol = Symbol("foo");
let globalSymbol = Symbol.for("foo");
console.log(localSymbol); // Symbol(foo)
console.log(globalSymbol); // Symbol(foo)
console.log(localSymbol === globalSymbol); // false
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. Boolean, String, and Number, all support constructors and can be used to initialize wrapped objects containing original values.

let myBoolean = new Boolean(a);console.log(typeof myBoolean); // "obecjt"

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

Use of symbols

Used as a property of an object

Wherever you can use strings or values as attributes, you can use symbols. For example, 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");
let o = {
  [s1]: "foo val"};console.log(o); // { [Symbol(foo)]: 'foo val' }
Copy the code

There’s more to notation, but I won’t go into it here. Because the relevant content needs to be supported by later knowledge, otherwise it is difficult to understand. And the symbol is really a very strange question, the interview will almost not be asked. Come back to know it better when you have time.