javaScript基础之隐式转换

隐式转换,这个是JavaScript,这个时候的一些java中的经验不但不会帮助自己,还有可能会错误的引导自己。

数据类型

JavaScript的变量可以分为三种方式,字面量形式,包装器方式,以及new创建变量(对象)

基本数据类型: 字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。

引用数据类型:对象(Object)、数组(Array)、函数(Function)。

上面之前的文章中有但是还有三个包装类

包装类: String Number Boolean

  • 通过这三个包装类可以将基本数据类型的数据转换为对象

    例如:

    ​ String() 可以将基本数据类型字符串转换为String对象
    ​ Number() 可以将基本数据类型的数字转换为Number对象
    ​ Boolean() 可以将基本数据类型的布尔值转换为Boolean对象

    注意:方法和属性能添加给对象,不能添加给基本数据类型。

    a=1;
    b=Number(1)
    c=new Number(1)
    
    typeof(a)  #"number"
    
    typeof(b) # "number"
    
    typeof(c) #"object"
    
    

    在这里插入图片描述

数据类型又分引用值类型基本类型。这个存储的有点像是java中的意思,也是分队和栈两个不同的存储类型。

在这里插入图片描述

这个现在可能没什么感觉,但是在JavaScript闭包等内容中会发现其神奇的之处。

其他数据类型隐式转换布尔类型

为什么会有这种隐式转换呢,现象看一个使用情况

if(12){
    
    
   console.log(12);
   }
# 在控制台输出
12
   

通过上面可以看出,数字类型其被转换成布尔类型了,不然也不会在if语句中生效。

以下可以看对应的布尔类型

数据类型 true false
Boolean true false
String 任何非空的字符串转换为true “” 这样的空字符串隐式转换false
Object 任何对象(非null)会转换true null 会转换false
Number 任何非O的数字(包括负数小数等) 0或者NaN
null 会转换为false
NaN 会转换为false
undefined 会转换为false

隐式转换中之 !

冒号(!)在很多语言中都有这个操作符,其作用是将操作符后面的数据转换成布尔类型,然后取反。

!后面的数据,会转换成布尔类型,其遵循的是其他数据类型隐式转换布尔类型表中的对应关系。

a=0
if (!a){
    console.log("输出")
    
}
# 第一步 将a现在转换为布尔类型的值
#第二步  !将a转换的布尔类型的值取反。
    

补充&&和||的神奇用法

先举例子:

a=1;
b=a;
if (!a){
    b=6;
    
}

#可以简写为
a=1;
b=a;
b=!a||6;

上面可以看出||的一个作用,其可以看出了神奇事情,简单的来说

#||  (| 一个的话 运算符)
遇见假就不会向后走,遇到真就向后走。

#&&  (& 一个的话就是位运算符,两个才是逻辑运算符)
遇见假就会向后走,遇见真就不会运行后面的。


(& 与 &&,|与||的详细区别详解,后面单独弄一篇。)

上面理解清楚的话,现在看一下代码

a=1;
34 && (function(){  a=45;})()

console.log(a)

#输出的的a
45

第一步: 34 遇见&& 就将其转换成布尔值

第二步:判断布尔值为true,所以运行&& 后面的的数据

第三步:(function(){...})() 会自动执行,所以其自动运行后将a的值进行重新赋值。修改了a的值


可以看出使用&&或者||可以修改很多东西。

(这个涉及到(function(){...})() 后面单独讲解,简单理解那就是可以自动运行这个function)

上面的例子,在很多js的页面中使用,设置在在逆向js中的时候,也是一种常见的方式,用来进行简单混淆。甚至还可以&&和||一起用。比如:

#a的值是什么
a =1 && null || 8 && function test(){
    
    } && !2

#得到的a的值为
false



#将上面的方法编程可自行运行
a =1 && null || 8 && (function test(){
    
    })() && !2

#得到a的值
undefined

补充:上面可以看出,在根据&&和|| 判断是否为真假然后运行后面,但是如果其最后最后赋值的时候,还是会得到其本身的值,比如带有自行运行的时候,因为没有return的数据,所以其本身是undefined,所以将其赋值给a.

隐式转换中之 ==

a=5
b="5"
console.log(a==b) #true
console.log(a===b)#false

前面说过,== 不像是===那样不但匹配其值是否相等还判断其是否类型一样。可见==比较a和b的时候既然返回的true,说明==也是涉及到了隐式转换。

先说规律吧,然后看下面的例子

与原始值使用==比较的时候

  • 如果两边类型不一致,其中一个是数字类型或者布尔类型,则两个都会转型成number类型。如果其中一个是引用类型,那就先调用valuesOf()方法,如果能转换成数字就可以对比,如果不能转换成数字的话,就需要调用tostring()转换成字符串。然后转成的字符串再转换为数字进行对比

    补充:valueOf() 返回指定对象的原始值。

​ 简单的说一下上面的隐式转换:当比较数字和字符串时,字符串会转换成数字值。 JavaScript 尝试将数字字面量转换为数字类型的值。

其中转换的时候用的是Number(字符串)进行转换。(不要使用parseInt()因最后的结果会不同,看下面的图)

在这里插入图片描述

如果是布尔类型呢?

在这里插入图片描述

这可以看出:

当数字通过==比较一个布尔类型的时候:先将布尔类型转换为数字类型(false对应的是0 true 对应的是1)

  • 如果两边类型不一致,没有数字类型或者布尔类型,而是字符串的话。如果其中一个是引用类型,那就先调用valuesOf()方法,如果能转换成数字就可以对比,如果不能转换成数字的话,就需要调用tostring()转换成字符串。

比如下面:

在这里插入图片描述

都是引用数据类型

  • 其对比的是存储的地址,所以下面两个转换成字符串虽然相等,但是其本身指向的堆的地址不同,所以不相等。

然后如果是两个对象呢?

在这里插入图片描述

以及下面包装类的Number和String进行对比

在这里插入图片描述

补充null、NaN、undefined

  console.log(NaN==NaN) //false
   console.log(undefined==null) //true
   console.log(null==null) //true
   console.log(null==undefined) //true

null、NaN、undefined ,相互比较的时候也不会参与隐式转换。

在这里插入图片描述

开始考试:

#第一题
new String('abc')==true

    第一步:true 转数字  new String('abc')==1
    第二步:new String('abc').valueOf()是字符串,所以不用调用tostring方法 : 'abc'==1
    第三步:abc通过number转换数字返回NaN   NaN==1
    第四步: NaN就不用再隐式转换了 结果:  false

# 第二题
[]==![]
   第一步:虽然数组[]是引用类型,但是后面的数组前面有个!那就强制转换布尔类型 []==!true
   第二步:!取反  []=false;
   第三步:布尔值转换数字  []=0
   第四步:数组[]中, []的valueof得不到原始值,所以调用tostring: ''==0
   第五步:空字符串转换成0,变成 0==0  所以返回值true

总结来说:

​ 1: 有基本数字类型和布尔值,==前后都变数。遇见引用先调用valueOf(),如若没有调tostring()。字符遵循number变数字。

​ 2:基本字符串对比引用数据,也是先调用valueOf(),如若没有调tostring()。

​ 3:引用数据比较数据存储地址。

​ 4:null、NaN、undefined ,相互比较的时候也不会参与隐式转换。

大于或小于符

这个数字比较大小,就不在陈述,遵守数学的规则。

字符串比较大小

如果其中一个是数据一个是字符串的话,会涉及隐式转换

在这里插入图片描述

在这里插入图片描述

因为a转换数字的时候会变成NaN,所以无论对比什么数字都是返回fasle。

如果两个字符串都是数字呢?

先看图片

在这里插入图片描述

可以看出字符串比较大小,不会转换数字,而是遍历元素,依次对比,只有一个不相等就会终止后面的对比

'23'>'4'
第一步:因为第一个'2'  通过charCodeAt方法  为50   4通过charCodeAt方法  为52
第二步: 对比50<52 所以 后面不会再继续对比,根据这个结果作为比较大小的结果
第三步:所以结果为false。

补充:charCodeAt方法会ascii码对照的数字。

这个时候有人就疑问了,既然对比数字,那么其对比干嘛写成字符串?其实这个涉及到要给方法sort方法。

在这里插入图片描述

可以看出,sort方法是将数字变成字符串,然后才进行比较的。

+号

加号,这个其实也会涉及到隐式转换,比如前面说过任何类型数据+字符串都会转成字符串。

  • 如果是两个原始数字类型相加直接遵循数学公式即可。

  • 任何类型加上字符串,都会变成字符串。

    • 原始数字

      "a"+1
      "a1"
      
    • 字符串+字符串自然就是连接在一起。

    • 字符串+引用类型数据

      这个时候就涉及到隐式转换了,引用类型先通过valueof方法得到其原始值,如果没有原始值就需要调用tostring方法,然后进行相加。

      a=[1,3,5]
      a+"test"
      第一步: 数组a的 valueof 得到不是原始值数据,所以调用tostring方法
      第二步: tostring调用的方法返回的数"1,2,5"
      第三步:所以最后结果为"1,2,5test""
          
      

      如果是null,undefined,NaN的话直接转化成字符串。

在这里插入图片描述

  • 如果是原始数据类型加上非原始数据类型(null,undefined,NaN,布尔值除外),那么就遵循转换字符串的规律,然后相加为一个字符串。

    • 布尔值 true为1,false为0

在这里插入图片描述

  • 数字+引用类型数据

在这里插入图片描述

  • null,undefined,NaN+原始数据类型

在这里插入图片描述

补充

对象类型valueof返回的原始值:

对象 返回值
Date 返回1970年1月1日0:00开始的毫秒数
Array 返回数组对象本身
Function 返回函数本身
Number 返回原始值数字
Object 一般返回对象本身
Boolean 返回布尔值
String 原始值的字符串
undefined,null,NaN等没有valueof方法

对象类型tostring返回的原始值:

对象 返回值
Array 以逗号分隔的由每个元素组成的字符串
Data 返回一个本地时间格式的字符串
Function 返回函数本身结构的字符串
Number 返回字符串类型的数值
Object [object Object]
Boolean 返回字符串的 true或者false
String 字符串
undefined,null,NaN等没有tostring方法

Guess you like

Origin blog.csdn.net/u011863822/article/details/121001460