类型转换

104 阅读9分钟

为什么要类型转换:Javascipt是弱数据类型(Js也不知道变量到底属于哪种数据类型,只有赋值了才清楚)

类型转换:显示:自己写代码告诉系统转成什么类型

              隐式:某些运算符被执行时,系统内部自动将数据类型进行转换

栈-基本类型:string number boolean null undefined symbol(es6新增)

堆-引用类型:object function array Date RegExp,特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math),其中Date和RegExp是function类型

包装类(将基本数据类型的数据转换为对象):string number boolean

String()可将基本数据类型字符串转换为string对象

Number() Boolean()同理

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

其他类型->字符串 数据.toString() String(数据) +str

toString对null和undefined会报异常

对象转换为字符串为"[object Object]"​

其他类型->数值 Number(数据) ParseInt(数据) ParseFloat(数据)+-*/%number

undefined 'one' {} ['a'] function(){}为NaN

null false '' []空白为0

对象转为NaN;

其他类型->布尔 Boolean(数据) (0 -0 NaN '' null undefined)为false,其他为true

空数组[]和空对象{}都是object类型,因此会被转化为true。

任意值与布尔值比较,都会将两边的值转化为Number。

如果将空数组[ ]与布尔值false比较,false转化为0,而空数组[ ]也转化为0,因此[ ] == false的判断得到true。

如果将空对象{}与布尔值false比较,false转化为0,而空对象{}转化为NaN,由于NaN与任何数都不相等,因此{} == false的判断得到false。

隐式

坑一:字符串连接符与算术运算符隐式转换规则混淆

坑一宝典string > number > boolean

null false '' []当作数值0; true '1' 当作数值1

坑二:关系运算符(> < >= <= == === != !==)会把其他数据类型转换成number再比较

坑二宝典[] false '' 当作数值0 ;{} NaN undefined null当作非数字NaN

注:null在遇到除== === != !==以外的关系运算符时将转换为0

但判断null == 0时,尽管 等号右端为数字,但null并未进行数值转换,所以此时,null为对象(空对象,无任何属性和方法),而0为Number类型,比较结果自然是false了

null是任何引用类型的默认值,不严格的说是所有object类型的默认值。

单个字符串比较unicode编码(始终遵循A<Z<a<b)

特殊情况:NaN==NaN //false null ==undefined //true null === undefined //false

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

①先使用valueOf()方法获取原始值,如果原始值不是number类型,则使用toString()转换为字符串

②再将这个string转成number运算

坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆

取正数、取负数:‘’ false []当作0;true [1]当作1;'a' NaN undefined [1,2] {} {a:1}当作NaN

引用数据类型比较数据存储地址(引用类型存在栈中,栈中存储的时地址)

转换为布尔值:一个逻辑非运算符(!)可以把值转换成布尔值并取反,两个逻辑非运算符就可以把值转换为正确的布尔值

                     当值包含至少一个字符的字符串,非0数字或对象时,Boolean()强制转换为true

                     如果字符时空字符串、数字0undefinednull

                     Boolean()强制转化

转换为对象:使用new命令调用String Number Boolean类型函数,可以把字符串、数字、布尔值转换为对应类型的对象

                     Object(true)//[Boolean:true]
                     Object.prototype.toString.call(new String(n))) 返回[Object String]
                     Object.prototype.toString.call(new Number(n))) 返回[Object Number]
                     Object.prototype.toString.call(new Boolean(n))) 返回[Object Boolean]

转换为简单值:在逻辑运算环境中,所有引用数据对象转换为布尔值的都为true

                     在数值运算环境中,对象会试调用valueOf方法,成功则该值参与运算,不成功再调用toString()方法,成功该值参与运算,不成功则会NaN参与运算。

若是数字字符串,则转换为对应的数字

若是非数字字符串或无法解析为数字的字符串,则会转换为NaN

若是布尔值true->1 false->0

若是null则被转换为0

若是undefined则被转换为NaN

                     在字符运算环境中,对象会调用toString方法获取对象的字符串表示;数组转换为简单值时,会调用toString()方法

获取一个字符串表示(若[]->"" ;若仅包含一个元素->取该元素值;若包含多个元素-》多个元素的值 )

                     在函数运算环境中,则会调用toString()方法获取字符串表示

转字符串

空值或没有提供参数时,返回空字符串

数字转字符串,直接将数字转换为对应的字符串形式

NaN被转换为字符串'NaN'

布尔值转字符串true转换为"true" false转换为"false"

null转换为字符串"null"

undefined转换为"undefined"

转对象

布尔值、数字、字符串分别被转换为对应的Boolean、Number、string对象

对于undefined、使用Object()转换为一个空对象{}

对于null使用Object()转换为一个空对象{}

对象转数字:

如obj是基本类型,则直接返回

否则先调用valueOf()如得到原始值则返回

否则使用toString()方法,如得到原始值则返回

否则报错

对象转字符串:

同对象转数字,唯一区别就是转字符串时,先调用toString()方法再调用valueOf()方法

对象转布尔:

对象转布尔值结果总是true

 注意:对于不同类型的对象来说,ToPrimitive的规则有所不同,比如Date对象会先调用toString,具体可以参考ECMA标准

注意:全局属性 NaN 的值表示不是一个数字,使用isNaN进行判断。

非严格相等== undefined和null 比较都是true 其他类型和undefined、null浅比较都是false console.log(null==undefined) //true

严格相等=== 严格相等存在两个特殊的判断: +0等于-0 NaN不等于NaN。 console.log(undefined===undefined) //true console.log(null===null)//true console.log(null===undefined) //false console.log(+0===-0) //true console.log(0===0) //true console.log(NaN===NaN) //false

零值相等&&同值相等 JavaScript中使用Object.is做同值相等判断,主要就是用来解决严格相等中正零负零、NaN的问题。 console.log(Object.is(+0,-0)) //false

console.log(Object.is(NaN,NaN)) //true

运算符优先级

后置+被用作字符拼接,其他类型大多是转成数值类型;

加法运算只要其中一个是字符串,那么另外一个也会转换为字符串;

数值加null或者undefined,那么还是把null或者undefined进行Number()转换。

! >算术运算符>关系运算符>&&>||>赋值运算符

对于&&来说:如果第一个为true,返回的是第二个值。相反,第一个为false,则直接返回这个值而不会执行后面的。

||这个与&&相反,如果第一个表达式的计算结果为true,则停止执行。反之,第一个计算结果为false,则继续向后执行。

1.基本类型和引用类型,他们的存值有什么区别?他们的回收机制又是怎么样的

内存中的位置的不同:基本类型栈中存放对应的值,按值访问;引用类型的值是同时保存在栈内存和堆内存中的对象,堆中存放对应的值,栈中存放指向堆内存的地址,按引用访问

原始值存储位置:栈stack中的简单数据段(变量访问的位置);堆heap中的对象,变量实际保存的是一个指针(地址),这个指针指向另一个位置。

参数传递不同:基本类型按值传递,引用类型按地址传递

赋值角度:基本类型在赋值操作后,保存与复制的是值本身,两个变量是相互不受影响的;引用类型保存与复制的是指向对象的一个指针,改变其中任何一个变量,都会相互影响

值得可变性:基本类型由于基本类型本身是没有方法和属性的,所以他的值是不可变的; 我们可为为引用类型添加属性和方法,也可以删除其属性和方法,说明引用类型可以拥有属性和方法,并且是可以动态改变的

占用空间:基本类型占用空间大小固定,被频繁使用;引用类型占用空间不固定,保存在堆中

回收机制: 栈stack为自动分配的内存空间,它由系统自动释放;堆heap是动态分配的内存,大小不定也不会自动释放,堆内存一般由程序员手动分配和释放

2.引用类型的地址存在哪里?它真实数据是存在哪里

引用类型的地址存在栈内,引用类型的真实数据存在堆中

3.显示转换和隐式转换区别

显示转换是指在代码中明确指定需要进行的类型转换操作。使用特定的转换操作符或者类型转换函数来实现。

隐式转换是指在编译器自动进行的类型转换,无需显式地指定转换操作。

4.为什么运算符优先级是从右往左计算的

5.为什么 0 == “” == false

两者做判断时,若有布尔类型,会先把boolean转换成number,即0 (false) 和 ""(false)

false==false==false

6.+”2”结果是啥

结果是数值2

'+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串

但“ + ” 是将某物转换为数字的最快且首选的方式,因为它不对该数字执行任何其他操作,如果它不能解析一个特定的值,它将计算为NaN

7.为什么他会比较unicode的编码

8.“上“

"SHANG" S结果为true

两个字符串比较,是将这两个字符串从左到右逐个字符比较。

由汉字组成的字符串可以参加比较。如”李红”

常见ASCII码的大小规则:09

9.函数加字符串

函数会调用toString方法转成字符串和字符串想加,最后的结果是拼接在一起的字符串

!!0

!0— false取反—true

!!0—true取反—false

!!null

!null—false取反—true

!!null—true取反—false