JS神奇的类型转换

js 专栏收录该内容
3 篇文章 0 订阅

众所周知JS是弱类型语言,弱类型语言的最大特点是允许隐式类型转换,即源码中没有明显的类型转换代码,也就是说你可以为一个变量赋值为字符串、也可以赋值为数值,也可以让不同类型的变量进行相加。语言的解析器会自动(隐式)转换。

隐式转换规则
1、转成string类型: + (字符串连接符)

2、转成Number类型:++/-- (自增自减运算符) ±*/%(算术运算符)> 、< 、>=、<=、、!=、=、!== (关系运算符)

3、转成boolean类型:!(逻辑运算符)

但是在实际应用中,我们总是会分不清 + 是作为字符串连接还是算术运算符。让我们看一下下面的列子,你觉得它会返回什么?

console.log( 1 + 'true')  
console.log( 1 + true )
console.log( 1 + undefined )
console.log( 1 + null )

正确答案是:

1true
2
NaN
1

让我们分析一下,首先要理解+什么时候作为字符串连接符什么时候为算术运算符,以及其作用。

字符串连接符(+ : 只要+号的两边有一边是字符串)
算术运算符 ( 两边都为数字 )
1、字符型连接符+ :会把其他数据类型调用string()方法转成字符串然后进行拼接。
2、算术运算符 + :会把其他数据类型调用number()方法转成数字然后再做加法运算

1+ "true" ----> String(1) + "true" ---> 1true
1+true -----> 1+ Number(true) ----> 1+ 1 -----> 2
1+undefined ----> 1+ Number(undefined)----> 1 + NaN ---> NaN
1+null -----> 1+ Number(null) -----> 1+ 0----> 1

关系运算符:把其他数据类型转成Number之后再进行比较

console.log( '2' > 10 )
结果为false  '2' > 10----> Number(2) > 10 ----> true
console.log( '2' > '10' )

结果为true,当关系运算符两边都是字符串的时候,同时转为number然后比较,但是此时比较的并不是按照number()转成的数字,而是按照字符串对应的unicode编码来转成数字。可以通过 str.charCodeAt() 来获取unicode

'2'.charCodeAt()---->50
'10'.charCodeAt()---->49
console.log( 'abc' > 'b' )

同理比较的也是unicode编码

'a'.charCodeAt()---->97
'b'.charCodeAt()---->98

特殊情况:

console.log( NaN == NaN  ) ----> false
console.log(undefined == null)  -----> true

复杂数据类型在隐式转换时会先转成string,然后再转成number运算

一个常见的面试题:

 var a = ???
    if(a == 1 && a == 2 && a ==3 ){
            console.log(1)
    }

我们可以利用复杂数据类型,调用valueOf()然后转成number,对象的valuueOf()方法也是可以重写的。

 var a = {
        i :0,
        valusOf: function(){
            return ++a.i   // 没调用一次就让a的i属性自增一次并返回
       }
   }

逻辑非隐式转换与关系运算符隐式转换


console.log ([] == 0 )
结果为true, [] ----> [].valueOf().toString() ---> '' == 0 ----> Number('') == 0;

那 ![] == 0的结果应该为true,还是false呢

答案是true。

要想理解,我们要先弄明白非(!)运算符

*逻辑非:将其他数据使用Boolean()转成布尔类型

只有以下八种情况转换为Boolean会得到false,除此之外都为true

0、-0、NaN、undefined、null、空字符串、false、document all()

我们再来看两个列子:

	 console.log( [] == [] );

    // false  原因:引用类型数据存在堆中,栈中存储的是地址,所以为false

    console.log( ![] == [] )

    [].valueOf().toString() ---> ''

    ![] -----> false 

    Number('') ==Number(false) ---> true
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值