JS的隐式转换 从 [] ==false 说起
前言
最近和大创扯淡时说到了[] == false,从结果上来看我俩都答错了,从气势上来说我俩的歪理都能出书了(恩,程序猿的骄傲),但是这其实背后隐藏了一潭很深的水,对,很深。。。
隐式类型转换
JS的数据类型
首先,回想一下JS的类型都有什么。
原始值(primitives): undefined, null, booleans, numbers,strings, symbol(es6)
对象值(objects): Object
ok, 这就是全部了,我们接下来看看到底发生了什么导致隐式转换如此不可捉摸。
ToPrimitive
在发生转换的时候,js其实都是会将操作对象转化为原始的对象,这也是最为诟病的地方,因为js很难直接抛出错误,她会用一套自己的方法去理解我们的错误,并做相应的调整,哪怕这些错误我们是无意识的。所以我们要知道她的转换方式,才能做到知己知彼,对代码的控制更为精准。
签名:ToPrimitive(input, PreferredType?) //PreferredType: Number 或者 String
流程如下:
- input为原始值,直接返回;
- 不是原始值,调用该对象的valueOf()方法,如果结果是原始值,返回原始值;
- 调用valueOf()不是原始值,调用此对象的toString()方法,如果结果为原始值,返回原始值;
- 如果返回的不是原始值,抛出异常TypeError。
其中PreferredType控制线调取valueOf()还是toString()。
ps: Date类型按照String去调用。
ok,通过这个隐式装箱,我们得到了操作数的原始值。接下来,我们根据不同情况,看看发生了什么呢~
数学运算
想必大家用过以下做法去完成类型转换吧
var str = '1';
var num = str - 0; var num = 2;
var str = num + '';
这种类似的数学运算会做类型转换,*,/和-操作符都是数字运算专用的。当这些运算符与字符串一起使用时,会强制转换字符串为数字类型的值。但是‘+’尤为致命,为啥捏?
当'+'作为双目运算符时,如a+b。
它的运行如下:
- 计算两个操作数的原始值: prima = ToPrimitive(a), prima = ToPrimitive(b);
- 如果原始值有String,全部转换为String,返回String相加后的结果;
- 如果原始值没有String,全部转换为Number, 返回Number相加后的结果;
当'+'作为单目运算符时, 例如 +a.
流程是这样的:
- 将a转换为Number,Number(a);
举个栗子:
[] + []
1. 转换为原始类型 toPrimitive([]); [].valueOf();//[],不是原始类型 [].toString();//"",真是令人发指的转换 2. 都为string,所以返回字符串想家的结果 return "" + "";
{} + [] 与 [] + {}
{} + []
1. 在浏览器中,JS引擎认为第一个{}为空代码块,所以 这里的 '+'是单目运算符(node中认为是对象,解析为"[object Object]")
ToPrimitive([]); //""
2. Number("");//
[] + {}
1. ToPrimitive([]); //""
ToPrimitive({}); //"[object Object]"
2. 都为string
return "" + "[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('');//
Number(false);// 3.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()就好了 (*^▽^*)
JS的隐式转换 从 [] ==false 说起的更多相关文章
- js数据类型隐式转换问题
js数据类型隐式转换 ![] == false //true 空数组和基本类型转换,会先[].toString() 再继续比较 ![] == [] //true ![] //false [] == [ ...
- js 的隐式转换与显式转换
隐式转换 1.undefined与null相等,但不恒等(===) 2.一个是number一个是string时,会尝试将string转换为number 3.隐式转换将boolean转换为numbe ...
- JS的类型转换,强制转换和隐式转换
JS的类型转换 1.强制转换 通过String(),Number(),Boolean()函数强制转换 var str=123; var str1='123'; console.log(typeof s ...
- js学习日记-隐式转换相关的坑及知识
隐式转换比较是js中绕不过去的坎,就算有几年经验的工程师也很有可能对这块知识不够熟悉.就算你知道使用===比较从而避免踩坑,但是团队其它成员不一定知道有这样或那样的坑,有后端语言经验的人常常会形成一个 ...
- js中的一些隐式转换和总结
js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false [] ...
- Js 中那些 隐式转换
曾经看到过这样一个代码: (!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]*~+[]]] = sb , 你敢相信, ...
- js中的数据类型隐式转换的三种情况
js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...
- ECMAScript1.1 js书写位置 | 声明变量 | 基本数据类型 | 数据类型转换 | 操作符 | 布尔类型的隐式转换
js书写位置 由于在写css样式时使用的时双引号,所以我们在写js代码时建议使用单引号(‘’)! 行内式 <input type="button" value="点 ...
- js隐式转换
JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object.object是引用类型,其它的五种是基本类型或者是原始类型.我们可 ...
随机推荐
- 一个比较实用的商业级图表Echarts
了解了解 ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼 ...
- Leetcode题解(十三)
36.Valid Sudoku 题目 代码如下: class Solution { public: bool isValidSudoku(vector<vector<char> &g ...
- Codeforces Round #383 (Div. 2) B. Arpa’s obvious problem and Mehrdad’s terrible solution
B. Arpa’s obvious problem and Mehrdad’s terrible solution time limit per test 1 second memory limit ...
- jquery.editable-select 可编辑下拉框之获取select值和input值
使用jquery.editable-select可以实现可编辑下拉框的功能,但需要先导入jquery.js,jquery.editable-select.css,jquery.editable-sel ...
- CSS浮动(Float)(二)
1.什么是浮动:在我们布局的时用到的一种技术,能够方便我们进行布局,通过让元素浮动,我们可以使元素在水平上左右移动,再通过margin属性调整位置 2.浮动的原理:使当前元素脱离普通流,相当于浮动起来 ...
- HTML5 Geolocation API工作原理[转载]
大家都知道,HTML5 Geolocation 可以使用 IP 地址.基于 Web 的数据库.无线网络连接和三角测量或 GPS 技术来确定经度和纬度. 问题: 在一个基于地理位置服务的个人业余项目(小 ...
- 使用Jquery.js框架和CSS3实现3D相册的制作
有关3D相册的制作主要包括以下几个知识点: 1.有关图片的位置摆放,也就是一个相对定位绝对定位的使用: 2.有关CSS3中transform属性的使用(transform-style: preserv ...
- canvas画布实现手写签名效果
最近项目中涉及到移动端手写签名的功能需求,将实现代码记录于此,供小伙伴们参考指摘哦~ HTML代码: <!--手写区--> <div class="mSign_signMa ...
- JavaScript数据可视化编程学习(一)Flotr2,包含简单的,柱状图,折线图,饼图,散点图
一.基础柱状图 二.基础的折线图 三.基础的饼图 四.基础的散点图 一.基础柱状图 如果你还没有想好你的数据用什么类型的图表来展示你的数据,你应该首先考虑是否可以做成柱状图.柱状图可以表示数据的变化过 ...
- Mac_Homebrew
Homebrew作为OS X上强大的包管理器,为系统软件提供了非常方便的安装方式,独特式的解决了包的依赖问题,并不再需要烦人的sudo,一键式编译,无参数困扰,真的,你值得拥有. brew 的安装: ...