Recently, I have been watching JS you don’t know.

Casts are classified as implicit and explicit casts, and although they have a bad reputation, it’s important to know what the rules of casts are.

Explicit casts improve code readability and maintainability by reducing confusion.

Implicit casts have “hidden” side effects, but some are also intended to make code more readable.

TL; DR

  • ToString: Primitive types and functions are quoted in place. But object, array conversion is troublesome point.
  • Json.stringify: not recognizedundefinedAnd functions, which can skip some values for objects. You can have a second and a third argument.
  • ToNumber: It’s hard to sum up…
  • ToBoolean: Only specific values can be converted tofalseEverything elsetrue
  • ParseInt: Parses a number from a string, stopping if it is not a number. Always pass a string with a base argument
  • Implicit transformation: various conditional expressions, addition, subtraction, multiplication and division, ><, ==.><Try to convert them into numbers before using them. As far as possible with= = =replace= =

ToString()

Generally xx.toString(xx) or String(xx) is used to display transformations.

Primitive types have a natural string-like form

String(null); // 'null'
String(undefined); // 'undefined'
String(true); // 'true'
String(1); / / '1'
String(1000000000000000000000.1); // "1e+21", slightly notice that if the number is very large or very small, it becomes an exponential
Copy the code
  • Normal object, will call the defaulttoString(), will return to the interior[[ Class ]]
  • Function, which returns the string form of the function
  • Array, will string each array, and then concatenate each string with **”,”**
String({}); // "[object Object]"(
String(function () {}); // "function(){}"
String([1.2{}]);/ / "1, 2, [object object]"
Copy the code

JSON.stringify(xx)

The string, number, Boolean, and NULL values are essentially the same as xx.toString() values in JSON stringification.

JSON.stringify(null); // 'null'
JSON.stringify(true); // 'true'
JSON.stringify(1); / / '1',
JSON.stringify(1000000000000000000000.1); // "1e+21", slightly notice that if the number is very large or very small, it becomes an exponential
Copy the code

However, all other types are different!!

  • encounterundefined,function, andsymbolWill automatically ignore them and returnundefined
  • encounterarrayIf the item is the value above, it will be replaced bynull
  • When an object is encountered, if the object has **toJSONThe ** method strings its return value. If it doesn’t, the conversion will skip the valueundefined,function, andsymbol.
JSON.stringify(undefined); // undefined
JSON.stringify(function () {}); // undefined
JSON.stringify([1.2.undefined.function () {}]); / / "[1, 2, null, null]"
JSON.stringify({ a: 1.b: 2.c: undefined.hello(){}});// "{\"a\":1,\"b\":2}"
JSON.stringify({
  a: 1.b: 2.toJSON() {
    return { a: this.a }; }});// "{\"a\":1}"
Copy the code

Json.stringify can take more than one argument

The second and third arguments are optional.

The second argument acts like toJSON, specifying a specific key stringification, either as an array or as a function. The function of the third parameter is the indentation of each level. Personally, this parameter is not useful, just know.

var a = { b: 1.c: 2 };
JSON.stringify(a, ['b']); // "{\"b\":1}"
JSON.stringify(a, function (k, v) {
  if (k === 'b') return v;
}); // "{\"b\":1}"
JSON.stringify(a, ['c'].The '-'); // "{\n--\"c\": 2\n}"
Copy the code

ToNumber

Conversions are typically displayed with Number(xx).

  • undefinedIf so, becomeNaN
  • nullIf so, become0
  • Booleaniftruebecome1.falsebecome0
  • String,onlyIntegers and decimals can be normal numbers, and everything elseNaN
Number(undefined); // NaN
Number(null); / / 0
Number(true); / / 1
Number(false); / / 0
Number('1.2'); / / 1.2
Number('1.2 d'); // NaN
Copy the code

Objects, as well as arrays, are first converted to the equivalent of the value of the primitive type, and then converted according to the rules above.

ValueOf (); xx.tostring (); Number(return value)

var a = {
  valueOf() {
    return '1';
  },
  toString() {
    return '2'; }};Number(a); / / 1

var b = { c: 1 };
Number(b); // NaN

var c = {
  c: 1.toString() {
    return{}; }};Number(c); / / an error
Copy the code

ToBoolean

Boolean(xx) is generally used to display transformations.

Convert other types of values to Boolean values, just remember which ones are converted to false and all others are true.

  • undefined
  • null
  • false
  • + 0.0.NaN
  • ""

Special attention:

  • Empty objects, empty functions, and empty arrays when converted to Booleantrue
  • When you create a primitive type with new, it’s also true when you convert it to Booleantrue
Boolean({} && [] && function () {}); // true
Boolean(new String(' ') && new Number(0) && new Boolean(false)); // true
Copy the code

Other explicit conversions

String(x)/Number(x)/Boolean(x) are all explicit conversions.

There are a few other recognized explicit conversions:

// number => string
1 + ' '= = =String(1);
// string => number
+'1'= = =Number('1');
// date => number Get the current timestamp equal to date.now () or new date ().getTime()
+new Date() = = =Number(new Date());
// Any type => Boolean!!!!!1;
Copy the code

Delta x is the same thing as minus x plus 1.

Sometimes, you can also see ~. In JS, indexOf is often used in conjunction with indexOf.

-1 is also another sentinel value, which in C means failure. JS indexOf returns -1, which means it was not found.

const isInclude = 'abc'.indexOf('d')! = = -1;
if (isInclude) {
  // ...
}
Copy the code

This is fine, but if you use ~, it’s more concise, and if you use it in if, you convert to Boolean

const isInclude = ~('abc').indexOf('d')
if (isInclude).indexOf('d')) {
  // ...
}
Copy the code

Parsing numeric strings: Not the same as casting

Parsing numeric strings: Parsing a number out of a string tolerates non-numeric characters — left to right, stopping parsing if non-numeric characters are encountered. Casts are not tolerated and fail to yield the value NaN.

Parsing should not be considered a substitute for casting

var a = The '42';
var b = '42px';

Number(a); / / 42
parseInt(a); / / 42

Number(b); // NaN
parseInt(b); / / 42
Copy the code

ParseInt works on string values, so never pass in a non-string, otherwise it will be cast to string.

ParseInt also has an optional second argument, which indicates how many bases (2-35) the string is translated into. The default is base 10, and the value of the second argument is always uploaded in progressive form. Note that the final result is returned in base 10.

parseInt('0x16'.10); / / 0
parseInt('0x16'.16); / / 22
parseInt('15'.10); / / 15
// 15 is a translation of hexadecimal, which translates into base 10 to 21
parseInt('15'.16); / / 21
Copy the code

Arguments that are not strings can do all sorts of weird things, so never pass a non-string

parseInt(1 / 0.19); // 18 ("I" from "Infinity")
parseInt(0.000008); // 0 ("0" from "0.000008")
parseInt(0.0000008); // 8 ("8" from "8e-7")
parseInt(false.16); // 250 ("fa" from "false")
parseInt(parseInt.16); // 15  ("f" from "function..")

parseInt('0x10'); / / 16
parseInt('103'.2); / / 2
Copy the code

Other implicit transformations

The -, *, and/operators implicitly change both sides to number

This is ok and easy to understand.

'1' - '2'= = = -1;
Copy the code

The + operator

Be careful with the plus operator, because when you add to a string, the other side will force it to be a string.

2 + 1 + '1'= = ='and';
Copy the code

> and <

This type can also be converted. To disambiguate, it is best to convert to a numeric type before using it.

var a = [42];
var b = '043';

a < b; // false -- string comparison!
Number(a) < Number(b); // true -- number comparison!

'1' - '2';
Copy the code

* -> Boolean

What kind of expression operation (implicitly) requires/enforces a Boolean transformation?

  • In aif (..)A test expression in a statement.
  • In afor ( .. ; . ; ..)The test expression for the header (second clause).
  • inwhile (..)anddo.. while(..)Test expression in the loop.
  • in? :A test expression in a ternary expression (first clause).
  • ||(” logical or “) and&&The operand on the left-hand side of the (” logical and “) operator (which is used as a test expression — see discussion below!)

Special note: a && and | | operators produce the value of not necessarily is a Boolean type. The resulting value will always be the value of one of the two operand expressions!

var a = 42;
var b = 'abc';
var c = null;

a || b; / / 42
a && b; // "abc"

c || b; // "abc"
c && b; // null

// It is often possible to write such code
var a = 42;
var b = null;
var c = 'foo';

If ("foo") = if("foo");
if (a && (b || c)) {
  console.log('yep');
}
Copy the code

= = and = = =

The conversion rules on both sides of == may be more than you think, so it’s best to just use ===.