美文网首页前端开发那些事儿
我所不知道的JavaScript——强制类型转换

我所不知道的JavaScript——强制类型转换

作者: 咕嘟咕嘟li | 来源:发表于2021-03-08 22:49 被阅读0次

    1. 值类型转换

    将值从一种类型转换成另一种类型,有两种情况,显示强制类型转换和隐式强制类型转换。

    var a = 66;
    var b = a + ''; // 隐式强制类型转换
    var c = String(a); // 显式强制类型转换
    

    2. 抽象值操作(ToString、ToNumber 和 ToBoolean)

    ToString: 非字符串到字符串的强制类型转换。String(value)

    基本类型值的字符串化规则:

    值类型 转换规则
    null "null"
    undefined "undefined"
    true "true"
    [] ""
    普通对象 "[object Object]"
    极小和极大的数字 指数形式

    如果对象有自己的 toString() 方法,字符串化时就会调用该方法并使用其返回值;

    var a = [1, 2, 3];
    a.toString(); // "1,2,3"
    
    JSON 字符串化

    对大多数简单的值都可以使用JSON.stingify(...)字符串化。

    • JSON.stringify(..) 在对象中遇到 undefined、function 和 symbol 时会自动将其忽略,在数组中则会返回 null
    var a = {
      name: 'Tina',
      age: 20,
      sayHi: function() {
        alert('Hi')
      },
      height: null,
      weight: undefined,
      hobbies: [
        'swimming',
        'reading',
        'singing',
        null,
        undefined,
        function () { console.log('hobbies') }
      ]
    }
    JSON.stringify(a)
    // "{"name":"Tina","age":20,"height":null,"hobbies":["swimming","reading","singing",null,null,null]}"
    

    如果要对含有非法 JSON 值的对象做字符串化,或者对象中的某些值无法被序列化时,就需要定义 toJSON() 方法来返回一个安全的 JSON 值。
    如果对象中定义了 toJSON() 方法,JSON 字符串化时会首先调用该方法,然后用它的返回值来进行序列化。


    图中循环引用会产生错误

    toJSON() 是返回一个能够被字符串化的安全的 JSON 值。

    JSON.stringify(value[, replacer [, space]])

    replacer表示要字符化的属性
    space用于美化输出

    var a = {b: 1, c: 2, d: 3}
    JSON.stringify(a, ['b', 'd']) //  "{"b":1,"d":3}"
    
    ToNumber: 非数字值到数字值 Number(value)

    非数字值到数字值转化规则:

    值类型 转换规则
    null 0
    undefined undefined
    true 1
    false, null 0
    转换出错 NaN

    ToBoolean: 转换为布尔类型 Boolean(value)

    JavaScript 中的值可以分为以下两类:
    (1) 可以被强制类型转换为 false 的值
    (2) 其他(被强制类型转换为 true 的值)

    假值:
    • undefined
    • +0, -0, NaN
    • false
    • null
    • ""
    假值对象
    var a = new Boolean(false)
    var b = new Number(0)
    var c = new String("")
    

    虽然 JavaScript 代码中会出现假值对象,但它实际上并不属于 JavaScript 语
    言的范畴。

    真值

    假值列表之外的值

    3. 强制类型转换

    3.1.1 字符串和数字之间的显式强制类型转换
    • 字符串与数字是通过 String(..) 和 Number(..) 这两个内建函数(比较常用)
    • .toString()
    • +(比较少用)
    var a = 42;
    var b = a.toString();
    
    var c = '66.6'
    var d = +c
    

    日期显式转换为数字

    var d = +new Date; // 可直接转换为时间戳, 不建议这么用,知道可以这么用就可以了
    var timestamp = Date.now();  // 获取时间戳
    

    ~运算符, 字位操作“非”

    var a = 'hello world'
    console.log(~a.indexOf('aaa')) // 0
    console.log(~a.indexOf('he')) // -1
    
    3.1.2 字符串和数字之间的隐式强制类型转换
    var a = [1,2];
    var b = [3,4];
    a + b; // "1,23,4"
    

    a和b都不是字符串,但是它们都被强制转换成字符串并拼接。
    类型转换都做了什么:

    • 调用obj[Symbol.toPrimitive] (hint)(如果存在)
    • 预期被转换成字符串类型,尝试toString()和valueOf(),否则退出。
    • 如如果预期被转换成默认类型或者数字类型时,尝试valueOf()和toString(),否则退出。

    也就是说,如果其中一个操作数是对象(包括数组),则首先对其调用ToPrimitive 抽象操作,该抽象操作再调用 [[DefaultValue]],以数字作为上下文

    [] + {}; // "[object Object]"
    {} + []; // 0
    

    第一行代码中,{} 出现在 + 运算符表达式中,因此它被当作一个值(空对象)来处理,[] 会被强制类型转换为 "",而 {} 会被强制类型转换为 "[object Object]"。

    第二行代码中,{} 被当作一个独立的空代码块(不执行任何操作)。代码块结尾不需
    要分号,所以这里不存在语法上的问题。最后 + [] 将 [] 显式强制类型转换为 0。

    3.2 显式解析数字字符串

    解析允许存在非数字的字符,从左到右,遇到非字符就停止
    转换不允许存在非数字字符, 否则返回NaN

    var a = "14";
    Number(a); // 14
    parseInt(a); // 14
    
    var b = "14px";
    Number(b); // NaN
    parseInt(b); // 14
    
    3.3.1 显式转换为布尔值 Boolean(value)

    常用方法是 !!, 为第二个!会将结果反转回原值

    var a = "0";
    var b = [];
    var c = {};
    var d = "";
    var e = 0;
    var f = null;
    var g;
    
    !!a; // true
    !!b; // true
    !!c; // true
    !!d; // false
    !!e; // false
    !!f; // false
    !!g; // false
    
    3.3.2 布尔值到数字到隐式转换
    1 + false // 1
    1 + true // 2
    
    3.4 || 和 &&

    && 和 || 运算符的返回值并不一定是布尔类型,而是两个操作数其中一个的值

    4. =====的不同

    == 允许在相等比较中进行强制类型转换,而 === 不允许

    == 判断的执行时间会比 === 的执行时间多

    1. 对于string,number等基础类型,== 和 === 是有区别的
      1)不同类型间比较,== 只比较“转化成同一类型后的值”看“值”是否相等,=== 如果类型不同,其结果就是不等
      2)同类型比较,直接进行“值”比较,两者结果一样

    2. 对于Array,Object等高级类型,== 和 === 是没有区别的
      进行“指针地址”比较

    3. 基础类型与高级类型,== 和 === 是有区别的
      1)对于==,将高级转化为基础类型,进行“值”比较
      2)因为类型不同,=== 结果为false
      === 的比较结果比 == 精准得多

    相关文章

      网友评论

        本文标题:我所不知道的JavaScript——强制类型转换

        本文链接:https://www.haomeiwen.com/subject/ifujqltx.html