JavaScript:undefined!=false之解 及==比较的规则
JS中有一个基本概念就是:
JavaScript中undefined==null
但undefined!==null
undefined与null转换成布尔值都是false
如果按照常规想法,比如下面的代码
var a=1;
alert(Boolean(a));//返回true
//那么下面的代码也应该返回true
alert(1==true); //但肯定的,下面的代码会返回false
alert(1===true);
但对于下面的代码,估计会让大部分JS程序员疑惑
alert(123==true);//为什么返回false alert(Boolean(undefined));//outputs false
alert(Boolean(null));//outputs false alert(undefined==false);//竟然返回false
alert(null==false);//竟然也返回false
至于其原因,下面作一个尝试性的解析(是尝试性的解析)
首先看看JS中的==比较是如何比较的
对于标量,“==”直接比较其中的值就行了
而对于两个对象(这里特指除去原始值的对象……因为在JS可以说一切皆对象)
则是比较其引用
因此对于两个对象的比较,看它们是不是同一个对象,是不需要用===(严格相等,值相等且类型相同)的
再深入分析下JS对于标量应用==比较时的情况
对于相同类型的两个标量的比较,除了NaN比较特殊之外(NaN==NaN返回false),都没什么疑点
而对于类型不同的两个标量的比较,JS就有一套严格的规则,这规则JS解析引擎具体怎样执行的,抱歉,还没去看JS解析引擎的源代码呢,这里只好对其表现作个总结
1.将Boolean,Number,String这三种类型进行不同类型的==比较时,其规则是,总将两边的值转换成数字,再看看转换结果数字是否相等
如下代码
alert(1==true);//true转换成数字也是1
alert('1'==true);//将字符串'1'与true都转换成数字 alert('abc'==true);//虽然字符串'abc'转换成布尔值是true,但这里会返回false
//因为'abc'转换成数字是NaN,而true转换成数字是1 alert(123=='123');//同理,true
而undefined与null,它们是简单类型还是引用类型呢?
将上面的规则 应用于undefined与null时就不正确了,在解析之前,先看看==比较的其它形式
JS中简单类型与引用类型进行==比较的情况
这种比较与是有规则的,并且可以用代码来验证JS内部的执行情况
将一个简单类型(这里指除undefined与null的值)与一个对象比较时,
先调用对象的valueOf方法,以期待返回一个标量,如果对象的valueOf方法返回的仍然是一个复合对象的话
就接着调用对象的toString方法以期待返回一个标量,如果仍然没有返回标量的话,就判为不相等
如果valueOf或toString方法之一返回一个标量,就用这个标量同==另一边的标量进行比较
var obj={};
alert(obj=="abc");//false
obj.toString=function () {
return 'abc';
};
alert(obj=='abc');//这时就返回true了
alert(obj==123);//false
obj.valueOf=function () {return 123};
alert(obj==123);//true!!!
obj.valueOf=undefined;//先将这个方法清空掉,以免受上面的代码影响
alert(obj==true);//false
obj.valueOf=function () {
return 1;//只要返回一个能转换成布尔值的标量就行了,1或true都行,都表示true
};
alert(obj==true);//true!!!!
事实上还可以用下面的代码进行验证,将一个复合对象与标量进行比较时,总会先调用对象的valueOf,
valueOf方法返回不是一个标量的话还会接着调用toString方法
var obj={
toString:function () {
alert('valueOf方法没有返回标量,我会被调用');
},
valueOf:function () {
alert('我先被调用,Object的valueOf方法默认实现是返回对象自身');
}
};
alert(1==obj);//可以看到执行次序
那么讲了这么多,这和undefined!=false有什么关系呢?
JS中的==对两边的对象进行比较时,undefined将被转换成数字,也就是说,undefined被看成基本值
而又由于undefined转换成数字为NaN,所以将Number,String,Boolean这三种类型与undefined比较时,总是返回false
而对于null,JS则将其当成对象来比较,即尝试调用null的valueOf与toString方法,再将返回的结果与另一个值进行比较,可以推断null==false返回false的原因是因为null的valueOf实现导致的
由于null没有valueOf与toString方法,因此始终返回false
ECMAScript规范是怎么说的?
ECMAScript规范中指出,a与b进行比较,如果a与b是Number,String,Boolean这三种类型中的一种,
并且a与b的类型不同,那么就将a与b都转换成数字再进行比较
也就是说
var a="true";
var b=true;
alert(a==b);
//结果等同于下面的代码
alert(Number(a)===Number(b));
而如果a是Number,String,Boolean这三种类型中的一种,而b是一个复合对象时(Object,Array等)
则对b执行ToPrimitive操作(这步是JS解释器执行的)
即
var a="abc";
var b={};
alert(a==b);
//上面的一行代码在JS解析时将被解释成
//a==ToPrimitive(b);
而这个ToPrimitive方法的实现,正是依次去调用对象的valueOf,toString方法,直到其中一个方法返回一个基本值
如果这两个方法没有返回基本值 ,那就认定不相等
而当a和b都是复合对象时,就很简单,就看a和b是不是同一个对象的引用!
而对于将undefined,null与其它类型进行比较的,则没具体说,只说了将
任何基本类型与Boolean类型比较时,会将其转换成数字(与前面的规则一样)
总结
Number,Boolean,String,Undefined这几种基本类型混合比较时,会将其转换成数字再进行比较
基本类型与复合对象进行比较时,会先将复合对象转换成基本类型(依次调用valueOf与toString方法)再进行比较
undefined被当成基本类型,undefined转换成数字是NaN,因此undefined与除null之外的其它类型值进行比较时始终返回false(注意NaN==NaN返回false)
null被当成复合对象,由于null没有valueOf与toString方法,因此和除了undefined之外的其它类型值进行比较时始终返回false
JavaScript:undefined!=false之解 及==比较的规则的更多相关文章
- undefined!=false之解 及==比较的规则
JS中有一个基本概念就是: JavaScript中undefined==null 但undefined!==null undefined与null转换成布尔值都是false 如果按照常规想法,比如下面 ...
- javascript return false 详解
在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页. Return False 就相当于终止符 ...
- JavaScript严格模式详解
转载自阮一峰的博客 Javascript 严格模式详解 作者: 阮一峰 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict m ...
- JavaScript数组方法详解
JavaScript数组方法详解 JavaScript中数组的方法种类众多,在ES3-ES7不同版本时期都有新方法:并且数组的方法还有原型方法和从object继承的方法,这里我们只介绍数组在每个版本中 ...
- js课程 1-3 Javascript变量类型详解
js课程 1-3 Javascript变量类型详解 一.总结 一句话总结:js对象点(属性方法),json对象冒号(属性方法).属性和方法区别只有一个括号. 1.json对象中的函数的使用? 函数名 ...
- javascript 操作cookies详解
javascript 操作cookies详解 这段操作cookies的方法我使用很久了,但是一直一来没遇到什么问题,今天在做一个在第一个页面保存了cookies,第二个页面获取或者第三个页面获取的功能 ...
- JavaScript(4)---BOM详解
JavaScript(4)---BOM详解 之前写过一篇有关DOM的博客:JavaScript(2)---DOM详解 DOM有个顶级对象叫:document.同样BOM中也有顶级对象叫 window. ...
- 从mixin到new和prototype:Javascript原型机制详解
从mixin到new和prototype:Javascript原型机制详解 这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...
- 什么是JavaScript闭包终极全解之一——基础概念
本文转自:http://www.cnblogs.com/richaaaard/p/4755021.html 什么是JavaScript闭包终极全解之一——基础概念 “闭包是JavaScript的一大谜 ...
随机推荐
- Python 文件操作(1)
今天大佬给了个A文件给我,里面存放了机密数据. 什么机密数据??? 有帅哥的联系方式吗? 赶紧打开来看一下 1.open() 函数基本版 Python大佬有个内置开文件的函数open(), 专门开文件 ...
- WebRequest与WebResponse抽象类,DNS静态类、Ping类
一.概述 1.WebRequest: 对统一资源标识符 (URI) 发出请求. 这是一个 abstract 类. WebRequest的派生类:PackWebRequest.FileWebReques ...
- IMEI手机串码和serialno
IMEI 1.IMEI是什么 国际移动设备识别码(International Mobile Equipment Identity number,IMEI),俗称“手机串号”.“手机串码”.“手机序列号 ...
- [2019年湘潭大学程序设计竞赛(重现赛)H chat][背包dp]
链接:https://ac.nowcoder.com/acm/contest/893/H来源:牛客网 题目描述 在Casya生活的世界里,一天由m个小时组成. 最近Casya的女神终于答应在接下来的n ...
- 基于steam的游戏销量预测 — PART 3 — 基于BP神经网络的机器学习与预测
语言:c++ 环境:windows 训练内容:根据从steam中爬取的数据经过文本分析制作的向量以及标签 使用相关:无 解释: 就是一个BP神经网络,借鉴参考了一些博客的解释和代码,具体哪些忘了,给出 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 【 题目:so easy】{并查集维护一个数的下一个没有被删掉的数} 补题ING
题意:给[1,n],n个数,有两种操作: 1 x,删去x2 x,查询还未被删去的数中大于等于x的最小的数是多少. input: output: 做法:按照并查集的方法压缩路径 代码: #include ...
- Spring boot请求参数
GET请求: 1.restful风格: @GetMapping("/order/detail") public BaseOutput omsQueryDetail(@Request ...
- 参数类型 (@Service层) interface 常用参数类型举例
public AdvMessage getMessage(String message, String type); public List<Map<String,Object>&g ...
- c实现双向链表
实现双向链表:创建.插入.删除 #include <iostream> #include <stdio.h> #include <string.h> #includ ...
- gitlab高可用模式
高可用模式 企业版 社区版 我们这里说一下成本比较低的主备模式,它主要依赖的是DRBD方式进行数据同步,需要2台ALL IN ONE的GitLab服务器,也就是通过上面安装方式把所有组件都安装在一起的 ...