JavaScript里值比较的方法

参考资料

Object.is

和 == 与 === 不同

  • == 运算符会对它两边的操作数做隐式的类型转换
  • === 也不会对操作数进行类型转换,但是它会把 -0 +0 这两个数值视为相同的,还会把两个 NAN 看成是不相等的。
+0 === -0 // true
-0 === 0 // true
+0 === 0 // true Object.is(-0, +0) // false
Object.is(+0, 0) // true
Object.is(-0, 0) // false NaN === NaN // false
Object.is(NaN, NaN) // true

这里,number 类型的数据有几种特殊的数值:

  • Number.NEGATIVE_INFINITY === -Infinity // true
  • Number.POSITIVE_INFINITY === Infinity // true
  • 21/0 === Infinity // true
  • -21/0 == -Infinity // true
  • 0/0 // NaN

Object.is 比 === 更严格。

隐式的类型转换

原始类型(Undefined、Null、Boolean、Number和String) + 对象类型(Object)

null 和 undefined

有一个传闻:

假如你打算把一个变量赋予对象类型的值,但是现在还没有赋值,那么你可以用null表示此时的状态(证据之一就是typeof null 的结果是'object');相反,假如你打算把一个变量赋予原始类型的值,但是现在还没有赋值,那么你可以用undefined表示此时的状态。

typeof null // object
typeof undefined // undefined

这里有一个图大概能表述清楚,几种类型相互的转换关系

几个概念

  • ToPrimitive:将操作数转为原始类型的值。
  • ToNumber:将操作数转
  • 类型的值都有一种向数字类型转化的趋势,底层就是依靠数值的比较

ToPrimitive

JavaScript引擎内部的抽象操作ToPrimitive()有着这样的签名:

ToPrimitive(input, PreferredType?)

可选参数PreferredType可以是Number或者String,它只代表了一个转换的偏好,转换结果不一定必须是这个参数所指的类型,但转换结果一定是一个原始值.如果PreferredType被标志为Number,则会进行下面的操作来转换输入的值 (§9.1):

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

如果PreferredType被标志为``String,则转换操作的第二步和第三步的顺序会调换.如果没有PreferredType这个参数,则PreferredType的值会按照这样的规则来自动设置:``Date类型的对象会被设置为String,其它类型的值会被设置为``Number.

ToNumber

下面的表格解释了ToNumber()是如何将原始值转换成数字的 (§9.3).

参数 结果
undefined NaN
null +0
布尔值 true被转换为``1,false转换为``+0
数字 无需转换
字符串 由字符串解析为数字.例如,"324"被转换为``324

如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用ToNumber()将这个原始值转换为数字.

下面的表格解释了ToNumber()是如何将原始值转换成数字的

参数 结果
undefined NaN
null +0
布尔值 true被转换为``1,false转换为``+0
数字 无需转换
字符串 由字符串解析为数字.例如,"324"被转换为``324

如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用ToNumber()将这个原始值转换为数字.

toString

通过toString()将值转换为字符串

下面的表格解释了ToString()是如何将原始值转换成字符串的(§9.8).

参数 结果
undefined "undefined"
null "null"
布尔值 "true" 或者 "false"
数字 数字作为字符串,比如. "1.765"
字符串 无需转换

如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, String)将该对象转换为原始值,然后再调用ToString(),将这个原始值转换为字符串.

valueOf

每个JavaScript固有对象的 valueOf 方法定义不同。

对象 返回值
Array 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。
Boolean Boolean 值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。

Math 和 Error 对象没有 valueOf 方法。

例子

{} == null?

ToPrimitive({}) => {}.valueOf() => {}.toString() => [object Object] => Number( [object Object] ) => NaN

null => Number(null) => 0

{} == null // false

{} + {} ?

ToPrimitive({}) => {}.valueOf() => {}.toString() => [object Object]

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

[''] == '' ?

ToPrimitive(['']) => [''].valueOf() => [''].toString() => '' => Number( '' ) => 0

'' => Number('') => 0

[''] == '' // true

JavaScript里值比较的方法的更多相关文章

  1. ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目

    ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml)   我们都知道在使用WebApi的时候Controller会自动将Action的返回值自动进行各种序列化处理(序列化为 ...

  2. Javascript中双等号(==)隐性转换机制 JS里charCodeAt()和fromCharCode()方法拓展应用:加密与解密

    Javascript中双等号(==)隐性转换机制   在Javascript中判断相等关系有双等号(==)和三等号(===)两种.其中双等号(==)是值相等,而三等号(===)是严格相等(值及类型是否 ...

  3. JavaScript里的循环方法总结

    JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.length; index++) ...

  4. 创建一个接口Shape,其中有抽象方法area,类Circle 、Rectangle实现area方法计算其面积并返回。又有Star实现Shape的area方法,其返回值是0,Star类另有一返回值boolean型方法isStar;在main方法里创建一个Vector,根据随机数的不同向其中加入Shape的不同子类对象(如是1,生成Circle对象;如是2,生成Rectangle对象;如是3,生成S

    题目补充: 创建一个接口Shape,其中有抽象方法area,类Circle .Rectangle实现area方法计算其面积并返回. 又有Star实现Shape的area方法,其返回值是0,Star类另 ...

  5. JavaScript里的循环方法之forEach,for-in,for-of

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  6. javascript里的sleep()方法

    很多编程语言里都有sleep(),delay()等方法,它能让我们的程序不那么着急的去执行下一步操作,而是延迟.等待一段时间.软件开发中经常会遇到需要这样的函数,比如等待几分钟去检查某一事件是否发生. ...

  7. JavaScript里的循环方法:forEach,for-in,for-of

    JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.length; index++) ...

  8. JS子父窗口互相操作取值赋值的方法介绍

    $("#父窗口元素ID",window.parent.document); 对应javascript版本为window.parent.document.getElementById ...

  9. JavaScript之call()和apply()方法详解

    简介:apply()和call()都是属于Function.prototype的一个方法属性,它是JavaScript引擎内在实现的方法,因为属于Function.prototype,所以每个Func ...

随机推荐

  1. mongodb: 安装 建/删 库,表

    mongodb的安装 下载mongodb www.mongodb.org 下载最新stable版 解压文件 3.不用编译,解压之后本身就是编译后的二进制可执行文件 解压之后,目录格式如下 在bin目录 ...

  2. mysql报错1872: Slave failed to initialize relay log info structure from the repository

    ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository 在一台主机上增加 ...

  3. Nginx配置SSL安全证书避免启动输入Enter PEM pass phrase

    之前两篇文章已经很好的介绍了Nginx配置SSL的一些情况,配置好的Nginx每次启动都要 输两遍PEM pass phrase,很是不爽,尤其是在服务器重启后,Nginx压根就无法自动启动,必须手动 ...

  4. 程序猿的量化交易之路(32)--Cointrade之Portfolio组合(19)

    转载须注明出处:http://blog.csdn.net/minimicall?viewmode=contents,http://cloudtrade.top/ Portfolio:组合,代表的是多个 ...

  5. Cocostudio学习笔记(5) Text + TextAtlas + TextBMFont

    下午一群大学生到我们公司參观学习,搞得我好紧张.于是滔滔不绝的给他们介绍了怎样开发一款游戏... 今晚研究的控件就是三个label:Text,TextAtlas,TextBMFont 我先在cocos ...

  6. 下一代Apache Hadoop MapReduce框架的架构

    背景 随着集群规模和负载增加,MapReduce JobTracker在内存消耗,线程模型和扩展性/可靠性/性能方面暴露出了缺点,为此需要对它进行大整修. 需求 当我们对Hadoop MapReduc ...

  7. Double类parseDouble()和valueOf()方法的区别

    数字类型的String字符串转换为浮点数通常采用parseDouble()和valueOf()方法, 两者主要是存在以下两点区别. 区别一:参数区别Double.parseDouble(java.la ...

  8. Java 学习 day01

    1. 基本常识 2. Java的跨平台性 3. Java环境搭建(安装) 4. Java环境搭建(环境变量配置) 5. Java环境搭建(环境变量配置技巧) 6. Java环境搭建(环境变量临时配置方 ...

  9. 【BZOJ3110】[Zjoi2013]K大数查询 树套树

    [BZOJ3110][Zjoi2013]K大数查询 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c,如果 ...

  10. EasyNVR H5流媒体服务器方案架构设计之视频能力平台

    历经过程 阶段一:经历过传统安防开发过程的开发者都有一种感觉,就是各种业务交织,各个模块的开发扯皮,各种数据库连接冲突,这很让开发工作效率很低,而且会给整体的开发带来负面影响,更重要的是,耦合度太高, ...