JS中的数据类型和类型转换

一、数据类型

 JS中的简单数据类型可以分为五种:Number 、String 、Boolean、Undefined 、Null。

Number:数字类型 ,整型浮点型都包括;

String:字符串类型,右数字字母字符串以及标点符号组成,必须放在单引号或者双引号中;

Boolean:布尔类型,只有true和false两种值;

Undefined:未定义,一般指的是已经声明,但是没有赋值的变量,如var a;

Null:空对象类型,var a = null,和var a=""有区别;"typeof null"会返回"Object"


复杂数据类型:Object

Object:对象类型,由一组无序的名值对组成。

Date:

RegExp:

Function:  

二、数据类型转换

【强制(显式)转换】——通过手动调用方法来转换

  • 转换为数值类型:Number(mix)、parseInt(string,radix)、parseFloat(string)
  • 转换为字符串类型:toString(radix)、String(mix)
  • 转换为布尔类型:Boolean(mix)

1、Number(mix):将任意参数mix转换为数值型

 (1)如果是布尔值,true和false分别被转换为1和0
 (2)如果是数字值,返回本身。
 (3)如果是null,返回0.
 (4)如果是undefined,返回NaN
 (5)如果是字符串,遵循以下规则:
         1、如果字符串中只包含数字,则将其转换为十进制(忽略前导0)
         2、如果字符串中包含有效的浮点格式,将其转换为浮点数值(忽略前导0)
         3、如果是空字符串,将其转换为0
         4、如果字符串中包含非以上格式,则将其转换为NaN

 (6)如果是对象,则调用对象的valueOf()方法,然后依据前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,再次依照前面的规则转换返回的字符串值。

2、parseInt(string, radix)函数,将字符串转换为整数类型的数值。它有如下的规则:

 (1)忽略字符串前面的空格,直至找到第一个非空字符 
 (2)如果第一个字符不是数字符号或者负号,返回NaN
 (3)如果第一个字符是数字,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止
 (4)如果上步解析的结果以0开头,则将其当作八进制来解析;如果以x开头,则将其当作十六进制来解析

    (5)如果指定radix参数,则以radix为基数进行解析

 

3、parseFloat(string)函数,将字符串转换为浮点数类型的数值。

  它的规则与parseInt基本相同,但也有点区别:字符串中第一个小数点符号是有效的,另外parseFloat会忽略所有前导0,如果字符串包含一个可解析为整数的数,则返回整数值而不是浮点数值。

4、toString(radix)方法。除undefined和null之外的所有类型的值都具有toString()方法,其作用是返回相应值的字符串表示。

5、String(mix)函数,将任何类型的值转换为字符串,其规则为:

 (1)如果有toString()方法,则调用该方法(不传递radix参数)并返回结果
 (2)如果是null,返回”null”

   (3)如果是undefined,返回”undefined”

  注意:区分 String() 和 new String() ,前者返回的类型是字符串,而后者返回的类型是对象。对于 Boolean() 和 new Boolean() 也是类似的。

 

6、Boolean(mix)函数,将任何类型的值转换为布尔值。

  以下值会被转换为false:false、”"、0、NaN、null、undefined,其余任何值都会被转换为true。

数据类型 转换为true的值转换为false的值
Booleantruefalse
String任何非空字符串“”(空字符串)
Number任何非零数字值0和NaN
Object任何对象null
UndefinedN/AUndefined

【隐式转换】——在某些情况的时候,即便我们不显式转换,JS也会自动转换

1、 用于检测是否为非数值的函数:isNaN(mix)

       isNaN()函数,经测试发现,该函数会尝试将参数值用Number()进行转换,如果结果为“非数值”则返回true,否则返回false。

2、递增递减操作符(包括前置和后置)、一元正负符号操作符

        这些操作符适用于任何数据类型的值,针对不同类型的值,该操作符遵循以下规则(经过对比发现,其规则与Number()规则基本相同):
    (1)如果是包含有效数字字符的字符串,先将其转换为数字值(转换规则同Number()),在执行加减1的操作,字符串变量变为数值变量。
    (2)如果是不包含有效数字字符的字符串,将变量的值设置为NaN,字符串变量变成数值变量。
    (3)如果是布尔值false,先将其转换为0再执行加减1的操作,布尔值变量变成数值变量。
    (4)如果是布尔值true,先将其转换为1再执行加减1的操作,布尔值变量变成数值变量。
    (5)如果是浮点数值,执行加减1的操作。

 

    (6)如果是对象,先调用对象的valueOf()方法,然后对该返回值应用前面的规则。如果结果是NaN,则调用toString()方法后再应用前面的规则。对象变量变成数值变量。

3、 加法运算操作符

        加号运算操作符在Javascript也用于字符串连接符,所以加号操作符的规则分两种情况:
如果两个操作值都是数值,其规则为:
    (1)    如果一个操作数为NaN,则结果为NaN
    (2)    如果是Infinity+Infinity,结果是Infinity
    (3)    如果是-Infinity+(-Infinity),结果是-Infinity
    (4)    如果是Infinity+(-Infinity),结果是NaN
    (5)    如果是+0+(+0),结果为+0
    (6)    如果是(-0)+(-0),结果为-0
    (7)    如果是(+0)+(-0),结果为+0

如果有一个操作值为字符串,则:
    (1)   如果两个操作值都是字符串,则将它们拼接起来
    (2)   如果只有一个操作值为字符串,则将另外操作值转换为字符串,然后拼接起来
    (3)   如果一个操作数是对象、数值或者布尔值,则调用toString()方法取得字符串值,然后再应用前面的字符串规则。对于undefined和null,分别调用String()显式转换为字符串。

    可以看出,加法运算中,如果有一个操作值为字符串类型,则将另一个操作值转换为字符串,最后连接起来。

补充:

加号作为一元运算符时,其后面的表达式将进行ToNumber操作,示例如下:

+true  // 1
+false // 0
+undefined // NaN
+null // 0
+'b'    // NaN
+'0x10' // 16
+{valueOf: ()=> 5} // 5
"a" + + "b"  // 输出结果 "aNaN"
// JS中的一元加的优先级高于2元加(减法也类似,一元减优先级高于二元减)
// 所以上述表达式可以等价于 "a" + ( +"b")
// "a" + NaN
// "aNaN"

4、 乘除、减号运算符、取模运算符

        这些操作符针对的是运算,所以他们具有共同性:如果操作值之一不是数值,则被隐式调用Number()函数进行转换。具体每一种运算的详细规则请参考ECMAScript中的定义。

5、 逻辑操作符(!、&&、||)

逻辑非(!)操作符首先通过Boolean()函数将它的操作值转换为布尔值,然后求反。
逻辑与(&&)操作符,如果一个操作值不是布尔值时,遵循以下规则进行转换:
(1)如果第一个操作数经Boolean()转换后为true,则返回第二个操作值,否则返回第一个值(不是Boolean()转换后的值
(2)如果有一个操作值为null,返回null
(3)如果有一个操作值为NaN,返回NaN
(4)如果有一个操作值为undefined,返回undefined
逻辑或(||)操作符,如果一个操作值不是布尔值,遵循以下规则:
(1)如果第一个操作值经Boolean()转换后为false,则返回第二个操作值,否则返回第一个操作值(不是Boolean()转换后的值)(2)对于undefined、null和NaN的处理规则与逻辑与(&&)相同

6、 关系操作符(<, >, <=, >=)

与上述操作符一样,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:
(1)如果两个操作值都是数值,则进行数值比较
(2)如果两个操作值都是字符串,则比较字符串对应的字符编码值
(3)如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较
(4)如果一个操作数是对象或者数组,则调用valueOf()方法(如果是数组则调用toString()方法),得到的结果按照前面的规则执行比较
(5)如果一个操作值是布尔值,则将其转换为数值,再进行比较
注:NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。

补充:

null / undefined 进行数学式或者关系操作符时,null会被转化为0, undefined会被转化为NaN。

奇怪的现象:null vs 0

null > 0   // false
null == 0  // false
null >= 0  // true

按理说,在最后一行代码显示“null 大于等于0”的前提下,前两句代码应该一定会有一个是正确的,然后事实却是结果都为false。

为什么会出现这种反常结果,这是因为相等性检测 == 和普通比较符 > < >= <= 的代码逻辑是相互独立的。进行值的比较时,null 会被转化为数字,因此它被转化为了 0。这就是为什么(3)中 null >= 0 返回值是 true,(1)中 null > 0 返回值是 false。

另一方面,undefined 和 null 在相等性检测 == 中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。这就解释了为什么(2)中 null == 0 会返回 false。

特立独行的undefined:undefined不应该被与其他值进行比较

undefined > 0   // false
undefined < 0  // false
undefined == 0  // false

(1)和(2)都返回false,是因为值比较时,undefined 被转化为NaN,而NaN是一个特殊的值,它与任何值相比返回都是false。而(3)返回false是因为这是一个相等性检测,而 undefined 除了与 null 值相等外,与其他值都不等。

7、 相等操作符(==)

相等操作符会对操作值进行隐式转换后进行比较:
(1)如果一个操作值为布尔值,则在比较之前先将其转换为数值
(2)如果一个操作值为字符串,另一个操作值为数值,则通过Number()函数将字符串转换为数值
(3)如果一个操作值是对象,另一个不是,则调用对象的valueOf()方法,得到的结果按照前面的规则进行比较
(4)null与undefined是相等的
(5)如果一个操作值为NaN,则相等比较返回false

(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象,如 [] != [] // true

具体实例,参考博文:https://blog.csdn.net/u012443286/article/details/79484095

8、全等操作符(===)

       全等操作符不会对两个操作数进行转换,直接进行比较,所以在比较上更加严格。日常中使用全等操作符几乎总是正确的选择。对于除了数值之外的值,全等操作符使用明确的语义进行比较:一个值只与自身全等。对于数值,全等操作符使用略加修改的语义来处理两个特殊情况:第一个情况是,浮点数 0 是不分正负的。区分 +0 和 -0 在解决一些特定的数学问题时是必要的,但是大部分情况下我们并不用关心。全等操作符认为这两个值是全等的。第二个情况是,浮点数包含了 NaN 值,用来表示某些定义不明确的数学问题的解,例如:正无穷加负无穷。全等操作符认为 NaN 与其他任何值都不全等,包括它自己。(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)

补充:

是否能实现(a==1 && a==2 && a==3) 或者(a===1 && a===2 && a===3) 为true?

(1)在==比较的情况下,会进行类型的隐式转换。前面已经说过,参数会进行类型转换,先valueOf再obj.toString() 所以,我们只要改变原生的valueOf或者tostring方法就可以达到效果:

// 每一次进行等号的比较,就会调用一次valueOf方法,自增1,所以能成立。当然,如果换个位置就不满足了。
var a = {
  num: 0,
  valueOf: function() {
    return this.num += 1
  }
};
var eq = (a==1 && a==2 && a==3);
console.log(eq);  // true

(2)在===的情况下没有类型转换,还是可以的。在vue源码实现双向数据绑定中,就利用了defineProperty方法进行观察,观察到数据的变化并实时反映到视图层。每一次访问对象中的某一个属性的时候,就会调用这个方法定义的对象里面的get方法。每一次改变对象属性的值,就会访问set方法。

var b = 1;
Object.defineProperty(window, 'a', {
    get: funtion() {
        return b++;
    }
})
var s = (a===1 && a===2 && a === 3 )
console.log(s)  // true;

 

【注意】参考博客:https://www.cnblogs.com/Juphy/p/7085197.html

 

                                        https://blog.csdn.net/qq_34356563/article/details/76718679

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值