你不知道的javaScript【笔记】--- js隐/显式转换

你不知道的javaScript【笔记】— js隐/显式转换

同学,来,先来一套迷之转换热热身

![]==[]   // 你猜
false==[]
''==null
''==0

是不是看的一脸懵逼?看完下面转换背后的规则再回来试试。


显示与隐式
首先显示转换和隐式转换式相对来说的,你明白这里要转换,那就是显示。你不明白,它还是会转换,它就是隐式,最直接的显示转换Number(),String(),Boolean(),注意都没用new操作符,所以返回的不是对象,而是进行相关转换。


三种常用转换的实现

1) ToString
在规范的9.8节中定义了抽象操作ToString(注意不是那个toString哦),它负责处理非字符串到字符串的强制类型转换。
基本类型值的字符串化规则是:
null=> ‘null’、 undefined=> ‘undefined’、 true=> ‘true’、 false=> ‘false’
数字的字符串化遵循通用规则。
关键是这里! 对象转换成字符串 是由抽象操作ToPrimitive完成的,它会先调用对象的toString()(这里除非自己定义了toString,不然都是返回对象的内部属性[[class]],Array.toString()就是例子),如果返回值是基础类型,就使用这个值。如果不是,就再调用原对象的valueOf方法,如果返回值为基本类型,就使用它强制转换成字符串,如果返回仍然不是基本类型,就报typeError的错误。

注意toString/valueOf都是自身没有,上[[proto]]找的(继承)

代码走一波
var obj={};
obj.toString()//  "[object Object]"   返回的是字符串,就用你了!
String(obj)   //  "[object Object]"   果然是这样。
obj.hasOwnProperty('toString') //false  自己没有。valueOf同理
obj.__proto__.hasOwnProperty('toString') //true 继承得来 

试试自定义valueOf和toString?
obj.valueOf=function(){return '我来自valueOf';}
obj.toString=function(){return '我来自toString';}
String(obj)  //先调用toString,返回 '我来自toString',转换成功。

改一下toString,让他返回非基本类型
obj.toString=function(){return {};}
String(obj)  // '我来自valueOf' 
//先调用toString,返回{},不是基本类型,调用valueOf试试,返回'我来自valueOf' 

自己修改valueOf试试看是不是TypeError: Cannot convert object to primitive value

*****这里强调一下Array.toString()
ArrayObject的子类,它自己重写了toString,结果类似与Array.join(',');
var arr=[null,undefined,0,1,true,'Nijat'];
arr.toString() // ",,0,1,true,Nijat"
arr.join(',')  //",,0,1,true,Nijat"
arr.__proto__==Array.prototype //true
Array.prototype.toString==Object.prototype.toString //false
删除这个屏蔽属性试试
delete Array.prototype.toString
Array.prototype.toString==Object.prototype.toString //true
arr.toString()  //"[object Array]" // 哈 是[[class]]




2)ToNumber
负责将非数字转换成数字,基本类型转换为

true---->1
false---->0
undefined---->NaN
null---->0  //为什么是0呢?因为它的内存地址里全是0 也是typeof null=='object'的原因
string---->内容是数值类型就转成数字,不然就是NaN(Not a Number) ''->0 记住这个!

object怎么转呢 ? 很简单,参考ToString,但是调用顺序不同,ToNumber是先调用valueOf() 如果返回基本类型,再用基本类型转换为数字的方法去转换,如果返回对象,就去调用toString(),是基本类型,就转,还不是,就报错typeError。自己写代码看看。


3)ToBoolean
只需要记住这些falsy value,只有他们的转换结果是false

false   null    undefined   ''  +0、-0   NaN

其他的,结果都是true,无论它看起来多奇怪,他都是true。比如这位

var a1=new Boolean(false)  //返回的可是对象
Boolean(a1)   //true  对象不是falsy value,所以。。。

OK,记住那三种转换规则,要开始用了~
直接看==比较时出现的隐式转换吧,这个看明白了,其他的都很简单。

1)数字和字符串比较,字符串转数字。注意NaN不等于NaN

2)其他类型和布尔类型之间的比较
这里有个大坑! 只要存在布尔值,就先把布尔值转数字,参考ToNumber()

var a = 666;
var b=true;
a==b; 
// 是不是会想a666,不是falsy value,所以他是true,true==true 完美!确实666,但不是这样转换的~~
首先,b是布尔类型,所以要先把它转成数字,true-->1,然后判断666==1 法克!结果是false

3)null 和undefined
这里我总结的是这样:

null==undefined         //true;
undefined==null        //true;
null==null            //true
undefined==undefined //true

除此之外的任何基本类型与null/undefined比较 结果都是false
''==null            //false
0==null             //false
 ...

4)对象和对象之间,不转换!不转换!不转换! 比较引用的地址。

5)对象和非对象之间
对对象使用ToPrimitive,参考ToString


同学,来,再做一遍试试

![]==[]   //true
// 先看左边 !显示转换boolean,[]不是falsy value,所以是true,!true-->false,现在呢,看看比较中有布尔值怎么处理,没错,先转数字,false-->0,现在是 0==[],成了对象与非对象之间,右边先toPrimitive(),是Array类型,它的toString()被重写过,所以是'', 原比较被转成了这样 0=='',数字和字符串比较,字符串转数字,记住Number('')结果是0,最后的最后 0==0? 所以结果是 truefalse==[] //true
''==null //false 只有undefinednull==nulltrue,其余都是false
''==0   //true

书中的解释和我的理解,有问题请指出

补充一点:判断类型的方法,最简洁和好使的一个:
Object.prototype.toString.call(xxx);
绕过各种toPrimitive,直接去取它的内部属性[[class]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值