Type conversions are one of the most frequently criticized techniques in Javascript. Douglas Crockford, author of “the Essence of Javascript”, has directly described them as “bad” or “bad”. It is said that the author often uses Javascript in his daily development. The worst thing about type conversions is that the + and == operations go too far. But Javasript type conversions are not useless. In order to let everyone use in the development process of comfort, rest assured, so there is this blog. I hope it’s helpful.

Here is the direct result of converting between types, if you don’t understand, then read on with questions.

+, = =, | |, &&

+ (emphasis)

1 + "1" / / '11'
1 + "string" // "1tring" (plus non-numeric string)
1 + true / / 2
1 + false / / 1
1 + [] / / "1"
1 + [1.2.3] 11, 2, 3 "/ /" 1 + {} // "1[object Object]" 1 + null / / 1 1 + undefined / / 1 null + undefined // NaN  true + 1 / / 2 true + "1" // "true1" true + "true" // "truetrue" (plus non-numeric string) true + true / / 2 true + false / / 1 true + [] // "true" true + [1.2.3] / / "true1, 2, 3" true + "true[object Object]" // NaN true + null / / 1 true + undefined // NaN  false + 1 / / 1 false + "1" // "false1" false + "string" // "falseString" (which adds a non-number string) false + false / / 0 false + true / / 1 false + [] // "false"  false + {} // "false[object Object]"  [] + 1 / / "1" [] + "1" / / "1" [] + "string" // "string" (plus non-numeric string) [] + true // "true" [] + false // "false" [] + [] / / "" [1] + [1] / / "11" [] + {} // "[object object]" [] + null // "null" [] + undefined // "undefined"  {} + 1 / / 1 {} + "1" / / 1 {} + "string" // NaN {} + true / / 1 {} + false / / 0 {} + [] // 0 (note!!) { a:1 } + [] // 0 (note!!) {} + [1] // 1 (note!!) {} + [1.2.3] // NaN (note!!) {} + {} // "[object Object][object Object]" {} + null / / 0 {} + undefined // NaN  -Infinity + Infinity // NaN Copy the code

Conclusion:

  1. If an operand is a string or can be converted to a string, + concatenates. See that the concatenation of strings has a higher “priority” than the + of numbers in the + operation.
  2. If an operand is an object (including an array), it is called firstToPrimitiveAction, which is then called[[DefalutValue]], with a number as the context, to ensure priority callvalueOf()Method, which is called inside the reference type when the + operation is performedvalueOf()methodspriorityabovetoString().
  3. Array or object being calledvalueOf()Method is called instead if it cannot get a value of the primitive type (number)toString().

Code demo:

// The valueOf() method is provided,
var daRui = {
    valueOf: function() {
        return 18
    },
 toString: function() {  return "daRUI"  } }  daRui + 7 / / 25 daRui + "Seven" / / "187" daRui + "hello" // "18hello"  // Only the toString() method is provided, var daRui = {  toString: function() {  return "daRUI"  } }  daRui + 7 // "daRUI7" daRui + " hello" // "daRUI hello"  Copy the code

Special note:

  1. In the arraytoString()The method is rewritten, so[1, 2, 3]It’s going to be “1,2,3”,[]Will change to “”.
  2. The object’stoString()Method returns “[object Class]”,Object.prototype.toString.call([])Return “[Object Array]”.
  3. [] + {}Get “object object”, and{} + []Get 0. This is because{}(curly braces) has two meanings in JS:
    1. when{}After +, denotes an object{}
    2. when{}In front of +,{}Represents an independentAn empty block of code, so{} + []The operation is equivalent to doing+ [](unary operator conversion operation) will[]To zero

== (key point)

1= ='1' // true
1= =true // true
1= = []// false
1= = [1] // true
1= = {}// false
 true= ="1" // true true= ="true" // false  true= = []// true true= = [1] // true true= = {}// false  [] = ="1"// false [] = =true // false [] = =false // true [] [] = =// false (note!!) [] = = {}// false [] = =! []// true (note!!)  {} = =1 // Unexpected token '==' {} = ="1" // Unexpected token '==' {} = =true // Unexpected token '==' {} = =false // Unexpected token '==' {} = = []// Unexpected token '==' = = {} {}// false (note!!)  "0"= =null // false "0"= =undefined // false "0"= =false // true (note!!) "0"= =NaN // false "0"= =0 // true "0"= ="" // false  false= =null // false (note!!) false= =undefined // false (note!!) false= =NaN // false false= =0 // true (note!!) false= ="" // true (note!!) false= = []// true (note!!) false= = {}// false  ""= =null // false ""= =undefined //false ""= =NaN // false ""= =0 //true (note!!) ""= = []// true (note!!) ""= = {}// false  0= =null // false 0= =undefined // false 0= =NaN // false 0= = []// true (note!!) 0= = {}// false +0= =0 // true  null= =null // true null= =undefined // true null= ="" // false null= =0 // false undefined= ="" // false undefined= =0 // false  NaN= =NaN // false can use isNaN() to determine if it is a NaN Copy the code

Conclusion:

The == operation is most important when converting two operands! ES5 specification 11.9.3 for the == operation gives clear specifications:

  1. Equality comparison between strings and numbers:

    1. Returns if Type(x) is a number and Type(y) is a stringx == ToNumber(y)Results.
    2. Returns if Type(x) is a string and Type(y) is a numberToNumber(x) == yResults.
  2. Comparison of equality between values of other types and Boolean types:

    1. This returns if Type(x) is a BooleanToNumber(x) == yThe results of the
    2. Returns if Type(y) is a Booleanx == ToNumber(y)The results of the
  3. An equality comparison between null and undefined

    1. If x is null and y is undefined, the result is true
    2. If x is undefined and y is null, the result is true
  4. Equality comparison between objects and non-objects:

    1. Returns if Type(x) is a string or number and Type(y) is an objectx == ToPrimitive(y)The results of the
    2. Returns if Type(x) is an object and Type(y) is a string or numbertoPrimitive(x) == yThe results of the
  5. Object to object comparison:

    1. In Javascript, objects are references, and comparisons between objects are essentially comparisons of memory addresses. So both are false.

      (Thanks for digg friends: Bug development engineer comrade correction)

In the == equality operation, if the operands on both sides are different, the type conversion is performed, and the operands are converted to numbers first and then compared. If the operands are still different, the type conversion is performed again until they are the same. Here is a string of type == Boolean:

  1. First the string type is changed to Number, and then the comparison isNumeric type == Boolean type
  2. And then we convert the Boolean type to Number, and then we compareNumber type == Number type

So that explains why “0” == false, right

If there is a reference type in the operand, this will first convert the reference type to the primitive type, and then perform the above operations for comparison.

[] ==! [] // true:

  1. Here! The priority of the operation is higher than ==,! [] First converts to false
  2. The comparison side is [] == false, where [] is converted to 0 again
  3. The comparison is 0 == false, and the rest is not hard to understand

!!!!! , &&, | | (key)

!!!!!

Converts a value to a Boolean value

 // Change all of the following to true
!!!!!""
!!!!!0
!!!!!0
!!!!! +0
!!!!!null !!!!!undefined !!!!!NaN Copy the code

, &&, | |

&& and | | is special in logical operators, the return is one of the two operands (and only one), or choose one of the two operands, and then return to its “value”. The two logical operators first perform a conditional on the first operand, and then perform a ToBoolean cast if it is not a Boolean.

For | |, if the condition judgment result to true will return the value of the first operand, if to false will return the value of the second operand.

&&, on the other hand, returns the value of the first operand if true or false.

— Javascript You Don’t Know, Volume 1

18 || "daRui" / / 18
undefined || "daRui" // "daRui"
18 && "daRui" // daRui
null && "daRui" // null
null| | {}/ / {}
null && {} // null Copy the code

Conclusion:

  1. && and | | return is one of the two operands, the strict sense is not a conversion, but a choice

  2. Daily development of the if (a | | b) {return true} process, is to get to a | | b value for judgment

  3. Here | | and && because it can simplify the code in our daily development, make the code more concise, example:

   18 || "daRui" 
   / / equivalent to
   18 ? 18 : "daRui"
   
   18 && "daRui" // daRui
 / / equivalent to  18 ? "daRui" : 18 Copy the code

References:

  • What you Don’t knowJavascript“In volume
  • JavascriptAdvanced Programming —
  • Write maintainableJavascript
  • ECMA5-262 standard

This article is formatted using MDNICE