你不知道的JavaScript中的数值转换

console.log(null == false);es6

开门见山,说出你的答案! 对,没错,答案是false! 让咱们一探究竟吧!数组

规定

先来阅读如下两份规则:bash

严格相等 === :ui

全等操做符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。若是两个被比较的值具备不一样的类型,这两个值是不全等的。不然,若是两个被比较的值类型相同,值也相同,而且都不是 number 类型时,两个值全等。最后,若是两个值都是 number 类型,当两个都不是 NaN,而且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。spa

var num = 0;
var obj = new String("0");
var str = "0";
var b = false;

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
复制代码

相等运算== :3d

The comparison x == y, where x and y are values, produces true or false.code

  1. 若是x不是正常值(好比抛出一个错误),中断执行。
  2. 若是y不是正常值,中断执行。
  3. 若是Type(x)与Type(y)相同,执行严格相等运算x === y。
  4. 若是x是null,y是undefined,返回true。
  5. 若是x是undefined,y是null,返回true。
  6. 若是Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果。
  7. 若是Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果。
  8. 若是Type(x)是布尔值,返回ToNumber(x) == y的结果。
  9. 若是Type(y)是布尔值,返回x == ToNumber(y)的结果。
  10. 若是Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果。
  11. 若是Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果。
  12. return false。

那么咱们提炼如下规则:cdn

  1. 若是 x或者y不是正常值,中断执行。
  2. 若是 typeof x 和typeof y相同,执行x === y。
  3. 若是 x和y分别是null和undefined,返回true。
  4. 若是 x和y分别是数值和字符串类型,那么返回 x == Number(y) (y 为字符串)
  5. 若是 x和y其中一个为布尔类型,那么返回x == Number(y) (若 x 为布尔类型)
  6. 若是 x和y分别是(Symbol值 或 数值 或 字符串) 和 对象,返回x == ToPrimitive(y) (若 y 为对象)
  7. return false

一、将值转为原始值,ToPrimitive()。对象

二、将值转为数字,ToNumber()。blog

三、将值转为字符串,ToString()。

1.ToPrimitive()

js引擎内部的抽象操做ToPrimitive有着这样的签名: ToPrimitive(input, PreferredType?) input是要转换的值,PreferredType是可选参数,能够是Number或String类型。他只是一个转换标志,转化后的结果并不必定是这个参数所值的类型,可是转换结果必定是一个原始值(或者报错)。

1.1若是PreferredType被标记为Number,则会进行下面的操做流程来转换输入的值。

一、若是输入的值已是一个原始值,则直接返回它
二、不然,若是输入的值是一个对象,则调用该对象的valueOf()方法,
   若是valueOf()方法的返回值是一个原始值,则返回这个原始值。
三、不然,调用这个对象的toString()方法,若是toString()方法返回的是一个原始值,则返回这个原始值。
四、不然,抛出TypeError异常。
复制代码

1.2若是PreferredType被标记为String,则会进行下面的操做流程来转换输入的值。

一、若是输入的值已是一个原始值,则直接返回它
二、不然,调用这个对象的toString()方法,若是toString()方法返回的是一个原始值,则返回这个原始值。
三、不然,若是输入的值是一个对象,则调用该对象的valueOf()方法,
   若是valueOf()方法的返回值是一个原始值,则返回这个原始值。
四、不然,抛出TypeError异常。
复制代码

既然PreferredType是可选参数,那么若是没有这个参数时,怎么转换呢?PreferredType的值会按照这样的规则来自动设置:

一、该对象为Date类型,则PreferredType被设置为String
二、不然,PreferredType被设置为Number
复制代码

toString()valueOf() 的用法有待补充。

2.ToNumber()

根据参数类型进行下面转换:

参数 结果
undefined NaN
null +0
布尔值 true转换1,false转换为+0
数字 无须转换
字符串 有字符串解析为数字,例如:‘324’转换为324,‘qwer’转换为NaN
对象 先进行 ToPrimitive(obj, Number)转换获得原始值,在进行ToNumber转换为数字

3.ToString()

根据参数类型进行下面转换:

参数 结果
undefined 'undefined'
null 'null'
布尔值 转换为'true' 或 'false'
数字 数字转换字符串,好比:1.765转为'1.765'
字符串 无须转换
对象 先进行 ToPrimitive(obj, String)转换获得原始值,在进行ToString转换为字符串

Object.is():

Object.is() 判断两个值是否相同。若是下列任何一项成立,则两个值相同:

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字而且
  • 都是正零 +0
  • 都是负零 -0
  • 都是 NaN
  • 都是除零和 NaN 外的其它同一个数字

这种相等性判断逻辑和传统的 ==运算符所用的不一样,==运算符会对它两边的操做数作隐式类型转换(若是它们类型不一样),而后才进行相等性比较,(因此才会有相似 "" == falsetrue 的现象),但 Object.is 不会作这种类型转换。

这与===运算符也不同。===运算符(和==运算符)将数字值-0+0视为相等,并认为Number.NaN不等于NaN。 示例:

Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var test = { a: 1 };
Object.is(test, test);       // true

Object.is(null, null);       // true

// 特例
Object.is(0, -0);            // false
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true
复制代码

实际运用

咱们先看如下如下几种值比较的结果:

这里写图片描述

挑选重点来分析以下:

[1,2] == "1,2" //true
复制代码

左边数组类型为Obeject,右边是String,知足总结条件6。 执行ToPrimitive([1,2]),在没有参数的状况下且不为Date类型,转换类型自动为Number 再执行 [1,2].valueOf(),类型仍是Obeject,不为原始值 再执行[1,2].toString()"1,2" 为字符串原始值 最后比较"1,2" == "1,2",返回true

开始的那个问题:

null == false; //false
复制代码

由于false是Boolean类型,知足总结中的第五条,因此实际比较

Number(bull) == false;
0 == null;
//false
复制代码

最新的 ECMAScript 标准定义了 7 种数据类型: 6 种 原始类型: Boolean Null Undefined Number String Symbol (ECMAScript 6 新定义) 和 Object

0 == null null的类型是Null,实际上这个比较不知足转换的任何一条规则,因此返回false

0 == NaN; //false
复制代码

两边都是Number类型,因此比较全等=== 返回false

NaN == NaN; //false
复制代码

从数值的角度上讲NaN不与任何值相等。

相关文章
相关标签/搜索