重学JS(十五)—— 让人抓狂的类型转换

偶然看到几道题,顿时心情就不好了

[] + {};
{} + [];
[1,2] + [2,3];
[] == 0;
1 + + "22" + 3;

是不是很绝望,叱咤前端几年,居然被这几道题目给制裁了。如果上述题目都会做了,那么,请忽略本文,我说的都是废话。
现在开始吧。

[]+{}

[] + {}; //[object Object]
{} + []; //0

纳尼,换个顺序结果还变了。
首先普及下+作为二元运算符的作用:

如果某个操作数是字符串或者能够转换为字符串的话,+将进行拼接操作,否则执行数字相加。如果一个操作数是对象(包括数组),那么首先会调用valueOf,再调用toString()。

对普通对象来说,除非自行定义,否则toString()返回内部属性[[Class]]的值,如“[object object]”。数组因为有自己的toString()方法,它会直接进行调用。看个简单例子:

let a = {
  toString(){
    return 1;
  }
}
a+1;  //2
1+{c:1}; //1[object Object]
[1,2]+[2,3];  //"1,22,3"

对象a因为有toString(),所以他转化为字符串的时候,会调用它并返回1,所以a+1实际生效的是1+1。
而{c:1}没有定义toString,所以1+{c:1}会转化为1+“[object Object]”。数组的toString会用逗号将各元素拼接起来,[1,2]+[2,3]实际转化为"1,2"+“2,3”。
那么换个顺序为什么执行结果会变?
原因是{}出现在左侧,被当成了一个独立的代码块,实际生效的是+[],一元操作符+号是用来强制转化为数字,[]被转化为了0,所以{}+[]结果是0。

1+ +"22" + 3

细心的读者应该有发现,两个加号间有个空格。如果没有这个空格就会报错,它会被识别成自加符号。
但是现在留了空格,这个+号就是和"22"绑定在一起了,它的作用是强制转化为数字,所以实际生效的是
1+22+3 = 26。
一元操作符+号,可能会出现在这里

let timestamp = +new Date; // 1537257889834

它将日期对象强制类型转化为了数字,返回结果是unix时间戳。这样的代码似乎可以装一波逼。

[] == 0

==号的计算结果会根据两边的数据类型来进行处理。

1、数字x和字符串y

返回x == ToNumber(y)的值

1 == '12'  //false
1 == '1'  //true

‘12‘转化为数字为12,自然和1是不相等的

2、其他类型x和布尔类型y

返回x ==ToNumber(y)的值。

'12' == true

在没看这篇文章前,这题肯定有人会答true吧。true被转化为1,实际生效的是‘12’ == 1,所以为false。

if(a){}  //正确用法
if(a == true){}  //错误用法,原理如上,42为真值,但不会等于true

同理

0 == false //true
1 == true //true

3、null 和undefined

null == undefined 为true,且它俩与所有其他值比较的结果都是false。

4、对象x和非对象y

返回ToPrimitive(x) == y的值。

ToPrimitive(obj)等价于:先计算obj.valueOf(),如果结果为原始值,则返回此结果;否则,计算obj.toString(),如果结果是原始值,则返回此结果;否则,抛出异常。

其实上文的加号运算符已经有讲到。但是有一点要注意,你可以重写ToPrimitive。回到之前的例子

let a = {
  toString(){
    return 1;
  },
  [Symbol.toPrimitive]() {
    return 2;
  }
}
a + 2; //4
a == 2; //true

该方法在转化基本类型时优先级最高。
回到题目[] == 0,数组的valueOf是自身,然后再调用toString()得到'',所以实际生效的是''==0。''又转化为数字0,所以[] == 0。
最后出几道题目,看看大家有没有掌握。

null == 0;
[] == ![];
[12] == 12;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容