2020-05-27

type conversion

Type Conversion

Primitive

JavaScript is a loosely typed or a dynamic language. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

There are 6 primitive data types: string, number, bigint, boolean, undefined, and symbol. There also is null, which is seemingly primitive, but indeed is a special case for every Object: and any structured type is derived from null by the Prototype Chain.

Except for null and undefined, all primitive values have object equivalents that wrap around the primitive values:

String/ Number /BigInt /Boolean / Symbol
The wrapper’s valueOf() method returns the primitive value.

Explicit coercion

![type converting](type-conversion/type converting.png)

Boolean()

Primitive to Boolean

1
2
3
4
5
6
7
8
console.log(Boolean()) // false
console.log(Boolean(false)) // false
console.log(Boolean(undefined)) // false
console.log(Boolean(null)) // false
console.log(Boolean(+0)) // false
console.log(Boolean(-0)) // false
console.log(Boolean(NaN)) // false
console.log(Boolean("")) // false

Number()

When Number is called as a function rather than as a constructor, it performs a type conversion.

Returns a Number value (not a Number object) computed by ToNumber(value) if value was supplied, else returns +0.

toNumber()

Type Result
Undefined NaN
Null +0
Boolean true value-> 1 false value-> +0
Number same number
String
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
console.log(Number()) // +0

console.log(Number(undefined)) // NaN
console.log(Number(null)) // +0

console.log(Number(false)) // +0
console.log(Number(true)) // 1
console.log(Number("123")) // 123
console.log(Number("-123")) // -123
console.log(Number("1.2")) // 1.2
console.log(Number("000123")) // 123
console.log(Number("-000123")) // -123
console.log(Number("0x11")) // 17
console.log(Number("")) // 0
console.log(Number(" ")) // 0
console.log(Number("123 123")) // NaN
console.log(Number("foo")) // NaN
console.log(Number("100a")) // NaN
1
2
3
4
5
6
console.log(parseInt("3 abc")) // 3
console.log(parseFloat("3.14 abc")) // 3.14
console.log(parseInt("-12.34")) // -12
console.log(parseInt("0xFF")) // 255 hexadecimal
console.log(parseFloat(".1")) // 0.1
console.log(parseInt("0.1")) // 0

String()

When String is called as a function rather than as a constructor, it performs a type conversion.

Returns a String value (not a String object) computed by ToString(value). If value is not supplied, the empty String “” is returned.

toString()

Type Result
Undefined “undefined”
Null “null”
Boolean true value-> “true” false value ->”false”
Number
String Same
1
2
3
4
5
6
7
8
9
10
11
12
13
14
console.log(String()) // 'empty string'

console.log(String(undefined)) // undefined
console.log(String(null)) // null

console.log(String(false)) // false
console.log(String(true)) // true

console.log(String(0)) // 0
console.log(String(-0)) // 0
console.log(String(NaN)) // NaN
console.log(String(Infinity)) // Infinity
console.log(String(-Infinity)) // -Infinity
console.log(String(1)) // 1

Primitive type to reference type

String()、Number() and Boolean() constructor with new keyword

1
2
3
4
var a = 1;
console.log(typeof a); // number
var b = new Number(a);
console.log(typeof b); // object

primitive to boolean

1
console.log(Boolean(new Boolean(false))) // true
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.

Object to string and number

first converts to primitive using toPrimitive, then convert to sting/number using ToString/ToNumber

Object.prototype
{
toString: ƒ toString()
valueOf: ƒ valueOf()
….
}

let a ={}
a.valueOf= function(){ return ‘run this method’}

1
2
3
let a ={a:'1'}
a.valueOf() //{a: "1"}
a.toString() //"[object Object]"
1
2
3
4
5
6
7
console.log(({}).toString()) // [object Object]
console.log([].toString()) // ""
console.log([0].toString()) // 0
console.log([1, 2, 3].toString()) // 1,2,3
console.log((function(){var a = 1;}).toString()) // function (){var a = 1;}
console.log((/\d+/g).toString()) // /\d+/g
console.log((new Date(2010, 0, 1)).toString()) // Fri Jan 01 2010 00:00:00 GMT+0800 (CST)

Implicit coercion

(👆The tricky part)

Abstract Equality Comparison (==)

Operand B
Undefined Null Number String Boolean Object
Operand A Undefined true true false false false false
Null true true false false false false
Number false false A === B A === ToNumber(B) A === ToNumber(B) A == ToPrimitive(B)
String false false ToNumber(A) === B A === B ToNumber(A) === ToNumber(B) A == ToPrimitive(B)
Boolean false false ToNumber(A) === B ToNumber(A) === ToNumber(B) A === B ToNumber(A) == ToPrimitive(B)
Object false false ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToNumber(B) A === B

To primitive:

ToPrimitive(A) attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.

type converting-Page-2
  • the piority of comparison type is Number > String >Boolean>Obj

  • if one side is number, then convert to number; else if one side is boolean, convert to number

  • true=='2'//false
    true->Number ->1
    '2'->Number ->2
    false=='a'//false
    true='a'//false
    'a'->Number->NaN
    <!--8-->
    
1
2
3
4
5
[] == ![] //true
left:ToPrimitive(![]) >> ToPrimitive(!ToBoolean([])) >>
ToPrimitive(!true) >> ToPrimitive(false) >> 0
ToPrimitive([]) >> ""
"" == 0 >> ToNumber("") == 0 >> 0 == 0 >> return true

‘+’ operartor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var a = 21;
var b = 4;
var c = '21';
var d = '4';
a + b; // 25
c + d; // "214"

var arr0 = [1, 2];
var arr1 = [3, 4];
arr0 + arr1; // '1,23,4'

console.log(+['1']); // 1
console.log(+['1', '2', '3']); // NaN
console.log(+{}); // NaN

|| && !

The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

1
2
3
4
5
6
7
8
let A = '';
let B = 1
A ||B //1
A && B //''
!B //flase
!A //true
A->Boolean->false ->OR run A
->AND run B

Ref:

ES5

Article