【JS之路】容易忽略的数据类型转换

前言

JavaScript作为一门弱类型的语言,即里面的变量的类型不是固定的。所以在JS里面类型转换发生的非常频繁。 本文梳理了以下知识点,希望能帮助到大家。

类型转换

JS类型转换大体分为两种:

  • 隐式转换:说明白点就是程序会自动进行的类型转换
  • 强制转换:即调用一些方法来实现类型转换

隐式转换


字符串加法运算

任何类型的数据和字符串类型的数据进行加法操作时,其他数据类型会自动转换为字符串类型,此时的+不是数学意义,是字符串拼接。

var result=“hello” + “ world”  //结果为“hello world    string
var result=1+1       //结果为   “11” 
var result=1+ true   // 结果为 “1true” 
var result=1+ undefined //结果为  “1undefined” 
var result=1+ null    // 结果为 “1null ” 

字符串其他运算

任何数据类型和字符串类型进行加法以外的运算(- * /),字符串要先转换为数字再去进行运算

  • 如果字符串为纯数字,则转换为相应的数字
 1-"11" // -10
  • 如果字符串中存在字符串以外的字符,则转换为NaN,NaN和任何数据类型运算都是NaN。
 1-"11a" // NaN

非字符串运算

除了字符串以外的数据,在进行运算(- * /)先转换为数字,再进行运算:

原数据转换后
true1
false0
null0
undefinedNaN
    1-true //  0
    1-false // 1
    1- null // 1
    1-undefined // NaN

非字符串运算中,+也是比较特殊的:

  • 当有一侧为数字时,其他数据为简单数据类型,则简单数据类型转换为数字类型
  • 当有一侧为引用类型,其他数据为任意类型,则将引用类型和其他数据均转换为字符串并进行拼接
  1 + null // 1
  1+ true // 2
  1+ {} // 1[object Object]
  true+{} //true[object Object]

逻辑运算

if语句和逻辑语句中,如果只有单个变量,会将其转换为Boolean值:

  • Number类型中:0 转换为 false;NaN转换为false
  • 字符串类型中:“”空字符串转换为false
  • null:转换为false
  • undefined:转换为false
  • object:[]、{}、function(){} 等都转换为true

== 和 ===

=====的区别:当 ==两侧的类型相同时,比较结果与 ===相同。因为==比较时会发生隐式转换,而===是恒等于,不仅内容相等而且数据类型一致。
==比较时发生的类型转换:

  • NaN
    只要存在NaN,则结果就为false(它和自己也不相等)
  • null和undefined
    把这两个放一起是因为 null==undefined 结果为true,此外,null、undefined和其他任何类型的结果都为false。
  • 简单数据类型和复杂数据类型:
    当简单数据类型和复杂数据类型进行比较时,复杂数据类型会依照ToPrimitive规则转换为简单数据类型:
    "[object Object]"=={} //true
    '1,2,3'==[1,2,3] //true

来看下面的例子:

 [null]==false //true
 [undefined]==false //true

根据数组的ToPrimitive规则,数组元素为null或者undefined时,该元素被当做空字符串处理,所以 [null]、[undefined]都转换为0


强制转换

  • Boolean()

    其他数据类型转换为布尔值:

    • Number:非0即真
    • 字符串:非空即真
    • nullundefined为false
    • []、{}、function()等为true
  • Number()

    其他数据类型转换为数字:

    • Boolean:true为1,false为0
    • 字符串:当字符串里面全是数字时,可以转换,其他转换为NaN
    • null为0,undefined 为NaN
    • [] 为 0; function(){}、{}为NaN
  • parseInt()

    对数字取整数:

    • 字符串:parseInt(“100a”) 结果为100; parseInt("10a1b) 结果为10; 如果开头不为数字,则为NaN
    • 把其他进制转换为十进制,必须传入字符串 parseInt(“1000”,2) 结果为8
  • parseFloat()

    对数字取浮点数

  • toString()

    其他数据类型转换为字符串


特殊的类型转换

在ECMAScript中规定,引用类型是一种数据结构,将数据和功能整合在一起。
我们平时所说的对象,其实就是某个引用类型的实例,这些引用类型可以是自定义的,也有特定的,例如:

  • Array数组
  • Date 日期
  • RegExp 正则
  • Function 函数

包装类型

在JavaScript中,为了方便操作基本类型、简化数据操作。ECMAscript还提供了几个特殊的引用类型,他们是简单数据类型的包装类型

  • Boolean
  • Number
  • String

包装类型和简单数据类型之间的转换也是一种特殊的类型转换

包装类型和简单数据类型的区别

    true===new Boolean(true); //false
    1===new Number(1) //false
    '123'===new String('123'); //false
    console.log(typeof new Number(1)) //object
    console.log(typeof 1) // number

以上是数据类型的区别。

他们的主要区别在于生存周期不同。用new关键字创建的引用类型的实例,在执行流离开当前作用域之前一直都保存在内存中,而简单数据类型只存在这行代码执行的瞬间,然后立即被销毁,这就意味着我们不能为简单数据类型添加属性和方法。


装箱和拆箱

幸好,JavaScript中的装箱拆箱机制使我们操作简单数据类型更方便。
先简单看一下装箱和拆箱的概念:

  • 装箱操作:把简单数据类型转换为对应的包装类型
  • 拆箱操作:把引用类型转换为简单数据类型
 var str="hello";
 var str1=str.substr(0,2);

我们刚刚说了,简单数据类型没有方法和属性,为什么上面代码能正确执行呢?
实际上发生了以下过程:

  • 创建一个String包装类型实例
  • 在实例上调用substr方法
  • 销毁实例

也就是说,我们在使用简单数据类型调用方法和属性时,会自动发生装箱和拆箱操作。


下面我们再讨论一下拆箱的具体过程。
从引用类型到简单数据类型,会遵循ECMAScript规定的toPrimitive原则,一般会调用引用类型的valueOftoString方法。 引用类型转换为不同简单数据类型时遵循的原则不同:

  • 引用类型转换为Number类型时,先调用valueOf,再调用toString
  • 引用类型转换为String类型,先调用toString,再调用valueOf

如果valueOftoString都不存在,或者重写方法没有返回简单数据类型,都会抛出typeError异常。

    var  obj1={
        valueOf: function(){
                 return 1;
        },
        toString: function(){
                return "123";
        }
    }
    console.log(obj1-1) //0
    console.log(obj+"456") //"123456"
    var  obj2={
        valueOf: function(){
                console.log('valueOf');
                 return {};
        },
        toString: function(){
                console.log('toString');
                return {};
        }
    }
    console.log(obj2-1) //valuseOf  TypeError

除了程序中的自动装箱和拆箱外,我们可以手动进行操作。我们可以通过new关键字实现装箱操作, 直接调用包装类型的valueOf或者toString,实现拆箱操作。

最后

本人也是第一次写笔记,文笔比较差,写这篇文章耗费的时间出乎我的意料,不过收获还是不错的。整理在CSDN上的目的:一是帮助同在学习前端的小伙伴,二是希望大家指出我的不足,一起进步。

以后的各类笔记我都会一一整理,希望在梳理知识的同时帮助大家快速掌握知识。

参考资料

https://juejin.cn/post/6844903854882947080

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值