zl程序教程

您现在的位置是:首页 >  前端

当前栏目

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

JavaScript转换 知道 数值
2023-09-27 14:29:04 时间

console.log(null == false);

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

规定

先来阅读以下两份规则:

严格相等 === :

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。

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
复制代码

相等运算== :

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

  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。

那么我们提炼以下规则:

  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

1、将值转为原始值,ToPrimitive()。

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

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

1.ToPrimitive()

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

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

1、如果输入的值已经是一个原始值,则直接返回它
2、否则,如果输入的值是一个对象,则调用该对象的valueOf()方法,
   如果valueOf()方法的返回值是一个原始值,则返回这个原始值。
3、否则,调用这个对象的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
4、否则,抛出TypeError异常。
复制代码

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

1、如果输入的值已经是一个原始值,则直接返回它
2、否则,调用这个对象的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
3、否则,如果输入的值是一个对象,则调用该对象的valueOf()方法,
   如果valueOf()方法的返回值是一个原始值,则返回这个原始值。
4、否则,抛出TypeError异常。
复制代码

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

1、该对象为Date类型,则PreferredType被设置为String
2、否则,PreferredType被设置为Number
复制代码

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

2.ToNumber()

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

参数结果
undefinedNaN
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不与任何值相等。


作者:Realucas
链接:https://juejin.im/post/5cd4d3ac5188255572734420
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。