JavaScript学习笔记(五):强制类型转换

类型转换

  • JavaScript为基本数据类型提供了封装对象,它们被称为原生函数(String、Number、Boolean),并且为基本数据类型值提供了特有的方法和属性(toString()、length)。
  • 基于基本类型的值,js引擎会自动对该值进行封装,来实现对这些属性和方法的访问。
  • toPrimitive抽象操作(内部使用的操作)包括toString、valueOf、toNumber、toBoolean。
字符串
  • toString()处理非字符串到字符串的转换,还有一些特殊的地方:

    • 数组的toString()经过了重新定义(你也可以),对所有的单元字符串化后再通过“,”连接起来;
    • json字符串化JSON.stringify()函数也涉及到toString的规则。JSON.stringify()只对安全型的JSON值做转换。不安全型的值:undefined、function、symbol以及对象的循环引用,遇到这类值时会被忽略,遇到循环引用则会报错。
    • JSON.stringify()第二个参数可以传入一个可选参数relpacer,可以是数组或者函数:
      • 数组必须是一个字符串数组,包含对象的属性名称,除了数组之外的属性以外,其他的值将会被忽略:
        const obj = { a: 1,  b: '2', c: 3 };
        console.log(JSON.stringify(obj, ['a', 'c'])); // {"a":1,"c":3}
        
      • 如果是函数,会对对象本身调用一次,然后对对象中的每个属性调用一次。
    • 第三个参数space可以用来指定缩进格式。
  • 隐式类型转换:’’ + x(一方是字符串时会被当作字符串拼接);

数字
  • Number()处理其他类型到数字的转换,如果无法换转回返回NaN(如function或者’111hhh’);
  • parseInt(只针对字符串)、parseFloat也能够(只针对浮点数);
  • 隐式类型转换:+(x)(“+”的一方不是字符串时会被认为是+法运算);“-”也可以,但写法上要注意:
    const n = '2'
    console.log(-n); // -2
    console.log(+n); // 2
    console.log(- -n); // 2 注意空格!
    
  • 字位运算符 “~”,强制将类型转换为32位数字然后对每一个字位进行反转,类似于 ~(x+1)。这么说可能会让人一头雾水,看下面的例子:
    const a = 'abcdefg'
    console.log(a.indexOf('de')); // 3
    console.log(~a.indexOf('de')); // -4 x +1 反转
    
    // 和indexOf可以将结果强制类型转换
    // 如果indexOf 返回 -1 ~会将其转为假值0,其他情况一律位真值
    if (~a.indexOf('de')) { // true
      console.log('找到你了');
      // ~~ 类似 !!
      console.log(~~a.indexOf('de')); // 3
    }
    
    • ~~还可以用来做字位截除(只适用于32位数字):
      const a = 3.333333
      console.log(~~a); // 3
      
布尔值
  • Boolean显示转换;
  • 在if()、for第二个表达式、while,三目运算符语句、等也会对值进行布尔值转换;
  • 隐式转换:! 或者 !!;
    const b = '';
    console.log(Boolean(b)); // false
    console.log(!b); // true
    console.log(!!b); // false
    
  • 逻辑运算符 || 和 &&,应该称为选择器运算符,会首先对第一个值进行强制类型转换(如果不是布尔值),然后再执行条件判断:
    • || 的规则是如果判断位true,返回第二个(或者为true)的那个值;
    • && 的规则相反如果条件为true,返回第一个变量的值。
宽松相等和严格相等
  • 误区:==检查值是否相等,===检查值和类型是否相等;
  • 正确的解释是:==允许再相等比较重进行强制类型转换,而 === 不允许。
    • 字符串和数字比较:

      • 如果 x是数字,y是字符串,则返回 x == toNumber(y);
      • 如果 x是字符串,y是数组,则返回 toNumber(x) == y;
      const a = '7';
      const b = 7;
      console.log(a == b); // true
      console.log(a === b); // false
      
    • 其他类型和布尔值比较:

      • 如果x是布尔值,则返沪 toNumber(x) == y;
      • 如果y是布尔值,则返沪 x == toNumber(y);
      const a = '7';
      const b = true
      const c = false
      // 是不是很奇怪
      console.log(a == b); // false
      console.log(a == b); // false
      

      注意,变量a是一个真值没错,但变量b或者c被强制类型转换为1和0,那么 a == 1 || 0吗?
      另外不要使用a == true此类的语法。

    • null和undefined比较

      • 如果x为null,y为undefined,结果为true;
      • 如果x为undefined,y为null,结果为true;
      • 也就是说再==中undefined和null是一回事。
    • 对象和非对象之间比较(布尔值会先被强制转换为数字):

      • 如果x是数字或者字符串,y是对象则返回 x == toPrimitive(y)的结果;
      • 如果x是对象,y是数字或者字符串则返回 toPrimitive(x) == y的结果;
      const a = ['7'] ;
      const b = '7'
      console.log(a == b); // 抽象操作toString() ‘7’ true
      
      const b = '7'
      const a = new String('7');
      console.log(a.valueOf()); // '7'
      console.log(a == b); // 在 == 时会“打开”封装对象,获取其原始值 true
      
总结
  • 显示强制类型转换有助于提高代码可读性和维护性,隐式类型转换的优点是使代码更加简洁;
  • 安全运用隐式强制类型转换:
    • 如果两边中的值有true或者false,不要用 ==;
    • 如果两边的值有[]、’’、0,尽量不要用 ==;
    • == 和 ===用哪个取决于是否允许在比较时发生强制类型转换。
  • 处理类型转换时要知其然还要知其所以然。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值