前言

最近和大创扯淡时说到了[] == false,从结果上来看我俩都答错了,从气势上来说我俩的歪理都能出书了(恩,程序猿的骄傲),但是这其实背后隐藏了一潭很深的水,对,很深。。。

隐式类型转换

JS的数据类型

首先,回想一下JS的类型都有什么。

原始值(primitives): undefined, null, booleans, numbers,strings, symbol(es6)

对象值(objects): Object

ok, 这就是全部了,我们接下来看看到底发生了什么导致隐式转换如此不可捉摸。

ToPrimitive

在发生转换的时候,js其实都是会将操作对象转化为原始的对象,这也是最为诟病的地方,因为js很难直接抛出错误,她会用一套自己的方法去理解我们的错误,并做相应的调整,哪怕这些错误我们是无意识的。所以我们要知道她的转换方式,才能做到知己知彼,对代码的控制更为精准。

签名:ToPrimitive(input, PreferredType?) //PreferredType: Number 或者 String

流程如下:

  1. input为原始值,直接返回;
  2. 不是原始值,调用该对象的valueOf()方法,如果结果是原始值,返回原始值;
  3. 调用valueOf()不是原始值,调用此对象的toString()方法,如果结果为原始值,返回原始值;
  4. 如果返回的不是原始值,抛出异常TypeError。

其中PreferredType控制线调取valueOf()还是toString()。

ps: Date类型按照String去调用。

ok,通过这个隐式装箱,我们得到了操作数的原始值。接下来,我们根据不同情况,看看发生了什么呢~

数学运算

想必大家用过以下做法去完成类型转换吧

var str = '1';
var num = str - 0;var num = 2;
var str = num + '';

这种类似的数学运算会做类型转换,*/-操作符都是数字运算专用的。当这些运算符与字符串一起使用时,会强制转换字符串为数字类型的值。但是‘+’尤为致命,为啥捏?

当'+'作为双目运算符时,如a+b。

它的运行如下:

  1. 计算两个操作数的原始值: prima = ToPrimitive(a), prima = ToPrimitive(b);
  2. 如果原始值有String,全部转换为String,返回String相加后的结果;
  3. 如果原始值没有String,全部转换为Number, 返回Number相加后的结果;

当'+'作为单目运算符时, 例如 +a.

流程是这样的:

  1. 将a转换为Number,Number(a);

举个栗子:

[] + []

1. 转换为原始类型 toPrimitive([]);[].valueOf();//[],不是原始类型

[].toString();//"",真是令人发指的转换2. 都为string,所以返回字符串想家的结果return "" + "";

{} + [] 与 [] + {}

{} + []
1. 在浏览器中,JS引擎认为第一个{}为空代码块,所以 这里的 '+'是单目运算符(node中认为是对象,解析为"[object Object]")ToPrimitive([]); //""2. Number("");//0
[] + {}
1. ToPrimitive([]); //""ToPrimitive({}); //"[object Object]"2. 都为stringreturn "" + "[object Object]";//"[object Object]"

PS: [].valueOf 为[], 但在ES6中JS会优先调用[Symbol ToPrimitive]来转换为原始类型。

比较运算

首先,比较运算分为2种, 一种为严格比较(===),只有类型相等,值也一致时才会为true,否则为false, 另一种为抽象相等也叫宽松相等(==),先将运算数转化为相同类型,再做比较,具体过程见 Abstract Equality Comparison Algorithm。

这个算法大致说了这么几个情况,x == y

  • xy都为Null或undefined,return true;
  • x或y为NaN, return false;
  • 如果x和y为String,Number,Boolean并且类型不一致,都转为Number再进行比较
  • 如果存在Object,转换为原始值,比较

回到这篇文章的导火索,[] == false

1.存在object, 转化为原始值
ToPrimitive([]); // ''2.一个string, 另外为boolean,都转为number
Number('');//0
Number(false);//03.return 0 == 0;/true

备注

ToPrimitive

 value toNumber  toString  toBoolean 
 NaN  NaN  "NaN"  false
 Infinity  Infinity  "Infinity"  true
 []  0  '""  true
 [1]  1  "1"  true
null 0 "null" false
undefined NaN "undefined" false
{} NaN "[object Object]" true
function() NaN "function" true

ToNumber

ToString

2017/12/05

winking说了一个简便的方法去理解[] toPrimitive = ‘’ , 想成join()就好了 (*^▽^*)

转载于:https://www.cnblogs.com/nanchen/p/7905528.html

JS的隐式转换 从 [] ==false 说起相关推荐

  1. html中隐式转换成数字,关于 JS 类型隐式转换的完整总结

    作者:原罪 来源:SegmentFault 思否社区 不管是在技术聊天群还是论坛里,总能碰到 x + y 等于多少的问题,比如 ,如果你不了解其中的原理,那么就插不上话,只能眼睁睁地等大佬解答了. T ...

  2. 从 ++[[]][+[]]+[+[]]==10? 深入浅出弱类型 JS 的隐式转换

    起因 凡是都有一个来源和起因,这个题不是我哪篇文章看到的,也不是我瞎几把乱造出来的,我也没这个天赋和能力,是我同事之前丢到群里,叫我们在浏览器输出一下,对结果出乎意料,本着实事求是的精神,探寻事物的本 ...

  3. 一文看懂JS里隐式转换、toString() 和 valueOf()

    js-看懂隐式转换toString 和 valueOf js隐式类型转换 数值类型和布尔类型的相加 字符串和数字相加 隐式类型转换隐藏一些错误 isNaN() 对象的隐式转换 强制类型转换 - &qu ...

  4. JS的隐式转换与显式转换

    隐式转换: 所谓隐式转换,就是当运算符在运算时,两边数据不统一,编译器会自动将两边数据进行数据类型转换成统一的再计算 常见隐式转换: 1.算术运算符:加(+).减(-).乘(*).除(/).取模(%) ...

  5. 从一道面试题说起—js隐式转换踩坑合集

    前方提醒: 篇幅较长,点个赞或者收藏一下,可以在下一次阅读时方便查找 提到js的隐式转换,很多人第一反应都是:坑. 的确,对于不熟悉的人来说,js隐式转换存在着很多的让人无法预测的地方,相信很多人都深 ...

  6. js return的值取不到_【JS基础】隐式转换(一)

    开篇 JS作为一门动态语言十分灵活,但是伴随而来的弱类型隐式转化的问题让我们十分头疼. 隐式作为一个大课题,很难用一个很简短的篇幅把JS的隐式转换讲解的十分清楚.所以我选择用多次少量的策略进行梳理,争 ...

  7. js date转成 时间字符串_秋招快要开始了,前端笔试中的坑位-JS隐式转换问题

    我们在写笔试题的时候,经常碰到涉及隐式转换的题目,例如 "1" + 2 obj + 1 [] == ![] [null] == false === 和 == === 叫做严格运算符 ...

  8. JS的类型转换,强制转换和隐式转换

    JS的类型转换 1.强制转换 通过String(),Number(),Boolean()函数强制转换 var str=123;var str1='123';console.log(typeof str ...

  9. js拼接字符串时数据类型的隐式转换

    数据类型的隐式转换:字符串类型string>数值类型number>布尔类型boolean数字+字符串:数字需要转成字符串 数字+布尔值:布尔值需要转成数字(true转成1,false转成0 ...

最新文章

  1. 使用Python,OpenCV生成Aruco标记
  2. python线性表和队列_[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列...
  3. iOS开发之AFNetworking 3.0.4使用
  4. map的用法-HD 1029Ignatius and the Princess IV
  5. 判断当前时间是否在某个时间范围内
  6. 再论推荐特征与embedding生成
  7. 不懂电脑如何买电脑_如何选择性价比高的电脑 买电脑要注意什么
  8. Myeclipse学习总结(10)——MyEclipse2014导入项目时The project was not built since its build问题
  9. 关于计算机组件游戏,老司机带你解决游戏运行提示缺少组件问题
  10. 永洪BI-报表生成URL
  11. 魅族4usb计算机连接,魅族MX4手机如何连接电脑
  12. 在手机与计算机之间进行文件传输的方式,电脑和手机传输文件方法_电脑和手机如何传文件-win7之家...
  13. 软考高级系统架构设计师:特定领域软件架构
  14. Log4J的入门简介学习【转】
  15. JAVA我的世界突然没声音_我的世界电脑版没声音怎么办
  16. All About Floats
  17. 决策树实现(CART生成及剪枝)
  18. markdown使用方法大全
  19. 等效结点荷载计算机语言,基于FORTRAN的3D等效结点荷载计算
  20. 互信息的深度理解(总结的不错值得一看)

热门文章

  1. iPhone has denied the launch request
  2. javascript console自动点击页面元素
  3. 大数据时代数据库-云HBase架构生态实践
  4. python进阶-面向对象编程四:包装授权和自定制列表某些方法
  5. 30年传奇 侯为贵留下的荣耀和遗憾
  6. 黄聪:WordPress 启用HTTPS设置(转)
  7. C#/ASP.NET定时任务执行管理器组件–FluentScheduler定时器
  8. 【性能优化】 之 HINTS 相关作业
  9. 传感器应用的demo自动录音器
  10. Android 高级Drawable资源---复合Drawable----层Drawable