类型转换

109 阅读3分钟

强制转换

  • 原始值转布尔
console.log(Boolean(NaN));

字符串除了空字符串'',都是true;

数字除了0,都是true;

null、undefined、NaN(一种数字类型)和什么值都不传都为false

  • 原始值转数字
console.log(Number(nu));
// 函数内部调用ToNumber(value)方法
console.log(parseInt(3.14, 2)); // 将3.14看成2进制数,转出十进制

字符串'0'转换成数字为0;'hello'转换成字符串为NaN;布尔的true转换成数字为1;null转数字为0;undefined转数字为NaN

  • 原始值转字符串
console.log(String(nu));
// 函数内部调用ToString()方法

num的NaN转换成字符串得到的是'NaN';num的Infinity(无穷)转换成字符串得到的是'Infinity';布尔值会转化成'true'和'false';undefined会转化成'undefined';null会转化成'null'

  • 原始值转对象

把string类型、number类型、布尔类型丢到String()、Number()、Boolean()中,即可转换成各自的包装对象。

let a = 1
console.log(typeof a);
let b = new Number(a)
console.log(typeof b); 

会得到额外的PrimitiveValue属性,会被计算机识别为包装类

  • 对象转布尔
console.log(Boolean(new Boolean(false))); //true
  • 对象转原始类型

    • toString

    各种类型调用toString方法的结果

    ({a: 1}).toString() // '[object Object]'
    [1, 2, 3].toString // '1,2,3'
    
    let a = function () {}
    a.toString() // 'function() {}'
    
    new.Data().toString // 中国标准时间的字符串
    
    • valueOf() 用于得到给定参数的原始数据类型
    ([1, 2, 3]).valueOf() // (3)[1, 2, 3]
    
    • ToPrimitive(input, PreferredType)

      如果PreferredType不存在,而input是Date类型,当相于PreferredType == String

      ToPrimitive(obj, Number)

      1. 如果obj是基本类型,直接返回
      2. 否则,调用 valueOf 方法,如果得到一个原始类型,则返回
      3. 否则,调用 toString 方法,如果得到一个原始类型,则返回
      4. 否则报错

      ToPrimitive(obj, String)

      1. 如果obj是基本类型,直接返回
      2. 否则,调用 toString 方法,如果得到一个原始类型,则返回
      3. 否则,调用 valueOf 方法,如果得到一个原始类型,则返回
      4. 否则报错 Object.prototype.toString.call({a: 1}) // "[object Object]"
    • JSON

    对象转字符串JSON.stringfy()

    字符串转对象JSON.parse()

  • 总结:js原始类型转换表

详见:www.cnblogs.com/jc2182/p/11…

隐式转换

  • 一元操作符 + 当 + 运算作为一元操作符时,会调用 ToNumber() 处理该值
// +'1'  Number('1')

// +[]  // 0
// +['1']  // 1
// +['1', '2', '3']  // NaN
// +{}  // NaN
  • 二元操作符 +

v1 + v2(ToPrimitive(v1) + ToPrimitive(v2))

  1. lprim = ToPrimitive(v1)
  2. rprim = ToPrimitive(v2)
  3. 如果 lprim 是字符串或 rprim 是字符串,那么返回 ToString(lprim) 和 ToString(rprim)的拼接结果
  4. 返回 ToNumber(lprim) 和 ToNumber(rprim)的相加结果
1 + '1' // '11'
null + 1 // 1
[] + [] // ''

[] + {} // '' + '[object, object]' => '[object Object]'

{} + [] // '[object, object]' + '' => 0({}被当做一个独立的代码块)

{} + {} // '[object Object][object Object]'
  • == x == y
  1. 如果 x 和 y 是同一类型

    1. x是Undefined,返回true
    2. x是null,返回true
    3. x是数字
      1. x 是 NaN ,返回 false(NaN不等于NaN)
    4. x和y指向同一个对象(指向同一地址),返回true,否则返回false
  2. null == undefined // (特例:没有值=找不到值)true

  3. 1 == 'h' // ==优先往number靠ToNumber('h') => false

  4. false == '1' // ToNumber(false) ToNumber('1')

  5. true == {a: 1} // true == ToPrimitive({a: 1}) => true == ({a: 1}).toString() => 1 == '[object Object]' => 1 == NaN

  • 总结

    • 在四则运算中,其中一方是字符串,就会把另一方也转成字符串
    • 在四则运算中,只要其中一方是数字,另一方就一定要转成数字
  • 附加题

    1. [] == ![] // 优先级先走感叹号 [] == false => [] == 0 => '' == 0 => 0 == 0
    2. [] == [] false
    3. [] + [] ''
    4. [] + [] '[object Object]'
    5. [] + {} 0

IEEE754浮点数标准

js存在精度丢失的问题,由于js遵从IEEE754浮点数标准

原理: 0.1转化成二进制:

0.1 * 2 = 0.2     0
0.2 * 2 = 0.4     0
0.4 * 2 = 0.8     0
0.8 * 2 = 1.6     1
0.6 * 2 = 1.2     1
0.2 * 2 = 0.4     0

产生循环,所以计算机会无限计算直到找到到达极限