数据类型转换
数据类型转换
对象转换为数字/字符串 【字符串拼接、数学运算、特殊方法处理、==比较(隐式转换、显式转换)。。。】
let obj ={
name:'xxx'
}
console.log(obj-10) // 数学运算:先把obj隐式转换为数字,再进行运算
//运行机制
obj[Symbol.toPrimitive] //undifined
obj.valueof() // {name:xxx}
obj.toString() // [object object]
Number ("[object object]") // NaN
NaN-10 // NaN
let xx=new Number(10)
console.log(xx-10) //0
xx[Symbol.toPrimitive] //undefined
xx.valueof() // 10
10-10 // 0
- 首先检测对象的Symbol.toPrimitive 这个属性, 获取其原始值
- 如果没有这个属性,则继续调用它的valueOf,也是获取原始值
- 如果值不是原始值,则继续调用toString转化为字符串
- 再把字符串基于Number转化为数字
==相等 ===全等 ==在比较的时候,如果两边类型不一致,则转化为相同的数据类型 NaN==NaN //false Object.is(NaN,NaN) //true null == undefined //true null===undefined //false null&undefined和其他任何值比较都是不相等的 对象==字符串 对象转换为字符串 剩余情况都是转换为数字
var a=?;
if(a==1&&a==2&&a==3){
console.log(ok)
}
这道题考察了上述运行原理的知识
var a={};
var i=0
a[Symbol.toPrimitive]=function(){
return ++i
}
if(a==1&&a==2&&a==3){
console.log('ok');
}
//或者
var a ={
i:0
}
a[Symbol.toPrimitive]=function(){
return ++this.i
}
if(a==1&&a==2&&a==3){
console.log('ok');
}
var arr= [1,2,3] //arr也是对象 所以也走对象转换的规则 arr.toString= arr.shift
第二类:es6 数据劫持
var i=0; //全局上下问中,基于var/function声明变量,也相当于给window设置了属性,window.a=12
Object.defineProperty(window,"a",{
get(){
return ++i
}
})
if(a==1&&a==2&&a==3){
console.log('ok');
}
js中的数据类型转换
把其他的数据类型转换为number类型 例如:==比较、数学运算(+不仅仅是数学运算,还有字符串拼接)。。。。。 显式转换方案:
- Number([val]) ->隐式转换一般调取的都是这个方法 【浏览器有自己的特殊处理,针对每一种】
- parseInt/parseFloat([val])
Number()
注:字符串转数字注意以下情况
- 空字符串 -> 0
- 空格 忽视
- 10进制以外的 例如: Number('0x0001') -> 1 剩下的情况下出现 非有效数字字符 都是NaN
parseInt([val],[radix])
parseInt([val],[radix])处理机制
-
[val] 必须是一个字符串,如果不是,则也要默认转换为字符串
-
[radix]不设置(或者写的是零):正常都是按照10处理的,如果字符串是以”0x“开始的,默认值是16... 先在[val]中,找到所有符合[radix]进制的内容(从左到右查找,直到遇到不符合的为止【不论后面是否还有符合进制的,都不在查找了】),然后再把找到的内容看做【radix】进制,转换为十进制 】。【radix】范围 2~36,除了0以外(0->10/16),不在这个范围内,结果都是NaN 例: parseInt('12px',1) -> NaN parseInt(null) -> null转字符串 'null' parseInt('null',10)-> NaN
进制转换
'10101' 2进制 —> 10进制 ^位权值 12^0 + 02^1 + 12^2+ 02^3 + 1*2^4
let arr=[27.2,0,'0013','14px',123]
arr=arr.map(parseInt)
console.log(arr)
//parseInt(27.2,0) parseInt('27,2')-> 27
//parseInt(0,1) ->NaN
//parseInt('0013',2) '001' 看作2进制 转换为10进制 1*2^0 ->1
//parseInt('14px',3) '1' 看作3进制 转换为10进制 1*3^0 ->1
//parseInt('123',4) '123'看作4进制 转换为10进制 3*4^0 ->3 + 2*4^1->8 + 1*4^2->16
把其他数据类型转换为布尔:
只有”0/NaN/null/undefined/空字符串“ 转换为false,其余都是true 例如: if(1){} ! 取反 !! 转换为布尔
+字符串拼接
+两边都有值,有一边 出现字符串或者对象,则为字符串拼接 特殊:{}+10->10 {}看做代码块 (es6块级上下文),真正的运算只有+10 ->10 10+{} -> "10[object object]" 原本是想把{}变为数字,但是Symbol.toPrimitive/valueOf/toString,调到toString变为字符串,此时符合了有一边变为字符串了,则是字符串拼接 +只有一边或者++x再或者x++,都是数学运算 +'10'->10 10+(++x) -> 先把x累加1,然后和10运算 10+(x++)-> 先拿x的值和10运算,最后再x累加1 x++ !== (x+=1 == x=x+1)
转载自:https://juejin.cn/post/6915989574141509639