likes
comments
collection
share

数据类型转换

作者站长头像
站长
· 阅读数 56

数据类型转换

对象转换为数字/字符串 【字符串拼接、数学运算、特殊方法处理、==比较(隐式转换、显式转换)。。。】

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
评论
请登录