type
Up to now (ES2021),JS has a total of eight built-in data types, respectively
- A null value (null)
- Undefined (undefined)
- Number (number)
- Boolean (Boolean)
- String (string)
- Symbol (symbol)
- Large integer (bigint)
- Object (object)
Bigint is a basic type added in ES2020. It is used to solve the problem that JS has lost the accuracy of large numbers. The maximum accuracy of ordinary numbers without bigINT is Number. The minimum precision is number.min_safe_INTEGER, which is 9007199254740991(2^53-1) and -9007199254740991 (-(2^53-1)) respectively. Beyond this range, accuracy will be lost.
const a = -9007199254740991 - 100;
console.log(a); / / - 9007199254741092
console.log(a === a - 1); // true
Copy the code
Bigint is designed to solve this problem. To create a bigInt, there are two ways.
const first = 10000000000000000000000n // Add n to the number
const second = const c = BigInt('100000000000000000000000000')
/ / n here if you need to create more than 100000000000000000000000000 the number of maximum safe value need to string figures, otherwise will still be super precision, because the parameter itself ultra precision
Copy the code
For more details, check out this article juejin.cn/post/684490…
Type judgment
typeof
All values except null get the correct type
const bool = true;
const num = 1;
const str = "hello";
const sym = Symbol("demo");
const obj = {};
const bigint = 1000000000000000000000000n;
console.log(typeof obj); // object
console.log(typeof bigint); // bigint
console.log(typeof undefined); // undefined
console.log(typeof null); // object <- special
console.log(typeof sym); // symbol
console.log(typeof str); // string
console.log(typeof num); // number
console.log(typeof bool); // boolean
Copy the code
The null type detection bug has been around for over 20 years and could cause more bugs if fixed, so it will not be fixed. So the way we determine null needs to be modified! a && typeof a === ‘object’
instanceof
This is a value that represents whether or not an object is built, so you’ll find that the underlying data type doesn’t work.
console.log(obj instanceof Object); // true
console.log(bigint instanceof BigInt); // false
console.log(sym instanceof Symbol); // false
console.log(str instanceof String); // false
console.log(num instanceof Number); // false
console.log(bool instanceof Boolean); // false
Copy the code
The basic type of boxing is generally in. Operator. Such as STR. CharAt (0)
Object.prototype.toString.call
This method can accurately obtain specific types, including object subtypes such as function and array
const arr = [];
const func = () = > {};
const getType = (value) = > Object.prototype.toString.call(value).slice(8, -1);
console.log(getType(arr)); // Array
console.log(getType(func)); // Function
console.log(getType(str)); // String
console.log(getType(num)); // Number
console.log(getType(bool)); // Boolean
console.log(getType(sym)); // Symbol
console.log(getType(bigint)); // Bigint
console.log(getType(null)); // Null
console.log(getType(obj)); // Object
console.log(getType(undefined)); // Undefined
Copy the code
Values and types
Variables don’t have types in JavaScript, only values. Because variables can be changed to other types of values at any time.
Undefined and undeclared
Undefined is declared in a scope but not yet assigned, and undeclared is undeclared. These two are different.
// undefined can use this judgment
let a;
if (a) {
// ...
}
// data are declared undeclared
if (b) {
//Uncaught ReferenceError: b is not defined
// ...
}
Copy the code
But the odd thing about JS is that using Typeof returns the same result in both cases
let a;
typeof a; // undefined
typeof b; // undefined
Copy the code
So we can use this feature to determine whether some values are already defined or declared
if (typeof DEBUG === "undefined") {
// ...
}
Copy the code
value
An array of
Unlike other languages, JS arrays can hold all other values and do not require a preset size. Arrays are indexed by numbers, but since arrays are objects in JS, they can also use string attributes, but not the length of the array.
const arr = [0.1.2.3];
arr["are"] = "you ok?";
arr.length; / / 4
Copy the code
And if a string can be cast to base 10, it is treated as a numeric index.
const arr = [];
arr["13"] = Awesome!;
arr.length; / / 14
Copy the code
For sparse arrays (arrays with vacant cells), some object methods of the array are skipped rather than passed undefined, such as map. The forEach, etc.
const arr1 = [0.2.3.4]
arr1.forEach(item= > console.log(item)) // 0 2 3 4
Copy the code
An array of class
Sometimes we need to convert an array of classes (a set of values indexed numerically) into a real array, such as a DOM list retrieved from a DOM query, arguments objects. We can do that
const arrayFrom = (value) = > Array.prototype.slice.call(value)
Copy the code
Or just use ES6’s new array method
const arrayFrom = Array.from
Copy the code
string
Strings are sometimes a bit like arrays because they all have methods like Length, indexOf, concat, and can also be indexed by numbers. But they are different, for example string numeric indexes can only be evaluated, not assigned
let arr = ['a'.'r'.'e']
let str = 'are'
arr[1] = 'u'
str[1] = 'u'
console.log(arr[1]) // u
console.log(str[1]) // r
Copy the code
Why does a string pass like an object when it is an underlying type? Operator to use method objects? This is because JS automatically does the boxing for us, and all the String methods we call are provided by the String function, including other underlying data types such as numbers. The same is true of Bull et al.
digital
Before Bigint, JS had only one kind of number, which already included “whole numbers” and decimal numbers with decimals. Integers are quoted because JS has no real integers. 40.00 is the same as 40. JS uses the IEEE754 standard, also known as floating point, in the double precision format (64-bit binary). As with string, numbers defined by literals can also use the methods in Number. Literals are generally defined in decimal.
let a = 666.66
a.toFixed(1) // 666.7 Round to preserve one decimal and convert it to a string
Copy the code
We can also define numbers in terms of exponents
const a = 1E3 // 1 times 10 ^ 3, which is 1000
Copy the code
Other formats are also supported
const a = 0xf3 // Hexadecimal 243
const b = 0o363 // Base 243
const c = 0b11110011 // Base 2 243
Copy the code
Problems with the IEEE754 standard
Any language that uses this standard has a hole in it
0.1 + 0.2= = =0.3 // false
Copy the code
In short, the binary floating-point numbers 0.1 and 0.2 are not quite accurate. 0.1+0.2 is actually 0.30000000000000004, so the result is false.
For JS, this Number is 2^-52. In ES6, this value is also defined in number.epsilon, so we can do this
function numbersCloseEnoughToEqual(val1, val2) {
return Math.abs(val1-val2) < Number.EPSILON
}
Copy the code
Some extreme values of numbers
- Maximum and minimum rendered numbers:
Number.MAX_VALUE
andNumber.MIN_VALUE
Represent the1.798 e+308
and5e-324
- Maximum and minimum safe integers:
Number.MAX_SAFE_INTEGER
andNumber.MIN_SAFE_INTEGER
Represent the2 ^ 53-1
and- 2 ^ 53 + 1
Special values
Null, and undefined
Null and undefined have only one value, themselves, and there is a slight difference between them.
null
: a null valueundefined
: there is no value
Undefined can be assigned in non-strict mode, which is a strange use. Never use it, just learn about it.
undefined = 2
Copy the code
Void operator.
Undefined is a built-in identifier, and its value is undefined unless redefined (see 👆 above), which we can get by using the void operator. The expression void XXX returns no value, so undefined is returned.
const a = Awesome!
console.log(void a) // undefined
Copy the code
Special numbers
-
NaN
NaN does not mean a number. It is the result of a failed numerical operation, for example
const a = 2 / 'hello' // NaN console.log(typeof a) // number but it is still a number... Copy the code
NaN has a special point that it is not equal to itself. NaN is the only value that is not reflexive. NaN! = NaN
So we can use this feature to determine if NaN is true.
if(a ! = a) {// ... } Copy the code
Or use the built-in function isNaN, but isNaN has a sore point
const a = Awesome! / 'hello' console.log(isNaN(a)) // true console.log(isNaN('hello')) // true... Copy the code
Obviously the string is not a NaN and it is not a number, but true is still returned. So we should all use the new Number. IsNaN in ES6 in the future.
const a = Awesome! / 'hello' console.log(Number.isNaN(a)) // true console.log(Number.isNaN('hello')) // false Copy the code
-
Infinity
const a = 1 / 0 // Infinity const b = -1 / 0 // -Infinity Copy the code
In JS, 1/0 does not return an error, but Infinity or -infinity (positive number.positive_infinity and negative number.negative_infinity).
Infinity is irreversible, which means that if you get an infinite value, that value will never become finite again
-
Zero value
JS has two zero values, 0 and -0. Addition and subtraction do not give you negative zero, only multiplication and division give you negative zero.
Stringing -0 yields “0”, but digitizing it the other way around yields the normal return value.
const a = -0 console.log(a.toString()) / / '0' console.log(JSON.stringify(a)) / / '0' const b = '0' console.log(JSON.parse(b)) / / - 0 console.log(Number(b)) / / - 0 Copy the code
A special equation
As I said, there are a lot of times when the result of the equation doesn’t necessarily match our intuition, like NaN is not equal to itself, 0 is equal to minus 0. In ES6, a new method object. is to determine whether two values are absolutely equal has been added to handle these special cases.
const a = Awesome! / 'hello'
console.log(Object.is(a, NaN)) // true
console.log(Object.is(0, -0)) // false
Copy the code
Of course, don’t use object. is when you can use == or ===, because the former are more efficient, and the latter is used only for special cases.
Value and reference
JS references refer to values, not variables. JS cannot make a variable point to another variable, but can only make the value of a variable refer to the value of another variable, that is, reference the same value.
JS reference to a value and assignment are no different in usage, completely determined by the value.
const a = 111
const b = a // assign a copy of a to b
const obj = { a: 1 }
const obj1 = obj // reference, obj1 refers to the value of obj. There is no copy operation in the middle, so both variables point to the same value.
Copy the code
So in general, assignment/passing is always done by copy for primitive types (which are all primitive types except objects) and by reference for complex types (objects). So references refer to values, not variables, and one reference cannot change the direction of another.
let arr = [1.2.3]
let cpArr = arr
arr = [4.5.6]
console.log(arr) / / (4 and 6)
console.log(cpArr) / / [1, 2, 3]
// Another example
function foo(arr) {
arr.push(Awesome!)
arr = [4.5.6]}const a = [1.2.3]
foo(a)
console.log(a) // [1,2,3,666] instead of [4,5,6]
Copy the code
Another point to note about references is that since the value of a reference is the same, changes to this value affect all variables that reference it.
const a = [1.2.3]
const b = a
a.push(Awesome!)
console.log(a, b) / /,2,3,666 [1], [1,2,3,666]
Copy the code