<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script>
/*
1.什么是隐式类型转换?
隐式类型转换就是在js中,当运算符进行计算时,当两边的类型不统一,此时就无法计算.
编译器会自动的把运算符两边的数据做一个数据类型转换,转换成相同的类型,然后再进行计算
2.隐式转换的规则
(1).转成string类型:+(字符串连接)
(2).转成number类型:++/--(自增自减运算符)
+ - * / % (算数运算符)>
< >= <= == != === !=== (关系运算符)
(3).转成boolean类型:!(逻辑非的方式)
*/
/**
原理分析:
1.字符串连接符+:会把其他类型调用string()方法转换为字符串然后拼接
2.算术运算符+:会把其他数据类I型那个调用number()方法住转成数字然后计算
*/
function jiaa(){
var a="true"
console.log(1+a)//字符串连接
//这个会把true转换为number(true)来计算,默认true转换为1
console.log(1+true)//2
//false默认转换为0
console.log(1+false)//1
//这个加是算数运算符 是把 1+number(undefined)=1+NaN=NaN
console.log(1+undefined)//NaN
//这个是算数运算符 1+number(null)=1+0=1
console.log(1+null)//1
}
jiaa()
/*
关系运算符:会把其他数据类型转换城number之后再比较关系
*/
function guanxi(){
//当关系运算符两边有一边是number时,会把字符串转为number类型,如果是其他类型,会转为number类型进行比较
console.log(2>"10")//false
//当关系运算符两边都是字符串的时候,会把他全部转为unicode编码的形式进行比较的
console.log("2">"10")
//当关系运算符两边都是字符串字母的时候,首先比较a与b的unicode编码,然后在比较b与b的unicode编码,以此类推
console.log("abc">"b")
//这个是比较第一位a与另一个字符串的第一位a的unicode编码,在比较b与aunicode编码,以此类推
console.log("abc">"aad")
//这一类是特殊情况:如果数据是null和undefined 得到固定的值
console.log(undefined==undefined)//true
console.log(undefined==null)//true
console.log(null==null)//true
//特殊情况:NaN与任何值比较都是NaN
console.log(NaN==NaN)//false
console.log((!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]*~+[]]])
}
guanxi()
/*
复杂数据类型在隐式转换时会先转换成string格式的,在转换城number类型
*/
function fuza(){
/*
1.复杂类型的数据转换如下:先把他用valueof()转换城原始值,如果原始值不是string,那么就用tostring()转换成字符串方式
2.再将string类型转为number类型那个
复杂类型的原理分析有点不严谨,应该是先调用valueOf方法,返回的值通过Number转换不是NaN的话,就拿返回的这个值作比较。
如果是NaN的话,就直接调用toString方法,得到的string类型转为number类型做比较
关于valueof()能够转成的原始值有:
array数组的原始值是数组实例对象
boolean获得的原始值是true和false
date获得的原始值是以毫秒存在的时间戳
function获得的原始值是函数本身
number获得的原始值是数字
object获得原始值是对象本身
string获得原始值是字符串
*/
//先将左边数组转为string,然后右边也是string,然后再转成unicode编码运算
console.log([1,2]=="1,2")//true
console.log([1,2].valueOf())//[1,2]
//一般来说number只能转数字类型,或者原始值本身字符串的数字转为数字等
console.log(Number([1,2].valueOf()))//NaN
console.log([1,2].toString())//'1,2'
//这里也是,先调用a的valueof()方法获取原始值,然后再调用tostring()方法
//转为字符串,最后再比较字符串的unicode编码进行比较
var a={}
console.log(a=="[object Object]")//true
console.log(a.valueOf().toString())//[object Object]
/*
分析:
逻辑运算一假则假,要想if分支语句小括号成立,则必须要a的值等于1,等于2,等于3
咋看之下,不可能实现,但是复杂数据类型会先调用valueof()方法,然后转成number去计算
而对象的valueof()方法是可以重新的
*/
var a={
i:0, //声明一个属性i
valueOf:function(){
retuen ++a.i
}
}
if(a==1&&a==2&&a==3){//因为这里每次运算都会调用一次valueof()方法,所有a会接着调用3次
//当a==1是调用一次,i+1
//当a==2是调用一次 ,i+1 此时的i是再保存值的
console.log("1")
}
}
fuza()
/*
逻辑非隐似转换与关系运算符隐式转换搞混淆
注意:
空数组的toString()方法会得到空字符串,
而空对象的toString()方法会得到字符串`[object Object]`
(注意第一个小写o,第二个大写O哟)
*/
function lpoi(){
/*
1.关系运算符;将其他数据类型转成数字
2.逻辑非:将其他数据类型使用boolean()转为布尔型
以下八种情况转为布尔类型会得到false:
*0,-0,NaN,undefind,null,"(空字符串)",false,documet.all()
除以上八种都是true
原理:
[].valueof().toString()得到空字符串
number(‘ ’)=0//true
*/
console.log([]==0)//true
/*
原理:
1.逻辑非优先高于关系运算符,![]=false (空数组转布尔值得到为true,然后取反得到false)
2.false=0
*/
//这里的这个逻辑运算符是高于关于运算符的所以![]直接就可以运算,,空数组转布尔值得到为true,然后取反得到false
console.log(![]==0)//true
/*原理:
1.{}.valueof().tostring()='[object Object]'
2.!{}=flase 这个是直接运算的 空数组转布尔值得到为true,然后取反得到false
3.number('[object Object]')=number(flase)
*/
console.log(!{}=={})//false
//而这个是因为是引用类型,都是再堆中引用的地址 所以为false
console.log({}=={})//false
/*
原理:
1.[].valueof().tostring()得到空字符串 为false
2.![]=flase
3.number('')==number(false)
*/
console.log([]==![])//false
//因为引用类型存储的都是引用的地址,所以都为false
console.log([]==[])//false
}
lpoi()
</script>
</body>
</html>
js之隐式类型转换总结
最新推荐文章于 2023-06-12 10:06:38 发布