JS深入之趣味比较隐式转换(一)

来源:互联网 发布:大学取消事业编制 知乎 编辑:程序博客网 时间:2024/05/16 09:10

真正接触过JS的读者都知道JS是一个弱类型语言,当你进行比较或者运算的时候,它会悄悄地给你转换一些东西,来来来,我们先试试如下这几个,同时也会讲述他们的比较的顺序和原理

1.对象和原始值比较

都是转换为原始值比较
我们构造这样一个对象

var a = {    toString : function(){        console.log('toString');    }};a == false;/*打印结果:toStringfalse*/

非常普通,这里我们可以发现当你比较一个对象和布尔类型的时候,他会悄悄运行toString函数,然后再进行判断,我们将代码又改为如下形式:

var a = {    toString : function(){        console.log('toString');    },    valueOf : function(){        console.log('valueOf');    }};a == false;/*打印结果:valueOffalse*/

加了一个valueOf函数,让人惊喜的是,valueOf被打印了出来,但是toString没有被打印。

如此我们基本就可以知道了一个对象跟布尔类型进行比较的时候会进行的转换,就是检查是不是存在valueOf函数,如果有就直接通过调用valueOf处理,如果没有就检查是不是有toString函数,如果有就调用toString,那布尔类型又是怎么转换的呢,如果不说Boolean对象的话,布尔类型一定是转换为数字,不管在什么条件下,布尔类型最终都是转换为数字,因为最开始是没有布尔类型的,布尔类型只是数字的特例而已。

然而这里需要注意的是Boolean对象,NumberString这些封装了原始值的对象,他们会让你懵逼。

好了,这里我们就大大的提到一个概念

就是两个值比较必须是同一类型的,什么呢,即便是你写成不同类型的比较,javascript处理也是尽可能将他们转换到相同的类型,如果转不了,是会报错的。

最简单的检验方法就是将上述的代码中的valueOftoString去掉,运行一下这份代码,分分钟钟报错。

{}==1

因为无法都转换为数字,所以比较不了,就会报错。

所以呢,由于基本数据类型即原始值都已经内部处理好转换问题了,所以我们比较一个数字和字符串,或者是布尔,又或者是nullundefined也好,都不会报错,只是比较的结果是true还是false而已,而针对Boolean这些对象,即便他们说的也是布尔类型啊,字符串类型啊,但是他们是封装原始值的对象,那么他们就会进行如下的规则转换比较,这个比较对所有的对象和原始值比较都适用,都一样。

如果是一个对象与原始值比较时,JavaScript会尝试返回对象的默认值,接着尝试将对象转换为其原始值。也就是说对于对象,是先返回他们的本身,看类型是不是一样,然后才去返回他们转换的原始值。

String.prototype.toString = function(){console.log('-toString')};String.prototype.valueOf = function(){console.log('-valueOf')};var b = new String('1');'1' == b;//这里返回false的原因是因为我的toString和valueOf没有返回值而已,但是能比较了并且打印出了-valueOf表明进行了转换

字符串以及数字的情况和这个一样,nullundefined排除在外。

2原始值和原始值比较

当我们的数字和字符串进行比较的时候,JavaScript 尝试将数字字面量转换为数字类型的值。 首先, 一个数学上的值会从数字字面量中衍生出来,然后得到被四舍五入后的数字类型的值,而布尔类型和数字比较也是转换为数字,其中原始值nullundefined比较就有点尴尬了,先跳过。

3.对象和对象比较

直接是比较他们的引用

4.nullundefined的畸形

针对undefined的比较,当我们用===的时候,只有当一个变量没有被赋值时就会返回true

var x;x===undefined

而当我们用==号时,还会检查x是不是null,如果是会返回true

5.=====使用时的注意事项

  1. 对于两个拥有相同字符顺序,相同长度,并且每个字符的位置都匹配的字符串,应该使用严格比较运算符。

  2. 对于两个数值相同的数字应该使用严格比较运算符,NaN和任何值不相等,包括其自身,正数零等于负数零。

  3. 对于两个同为true或同为false的布尔操作数,应使用严格比较运算符。

  4. 不要使用严格比较运算符或比较运算符来比较两个不相等的对象。

  5. 当比较一个表达式和一个对象时,仅当两个操作数引用相同的对象(指针指向相同对象)。

  6. 对于NullUndefined 类型而言,应使用严格比较运算符比较其自身,使用比较运算符进行互相比较。

6.知识提升

我们前面对于nullundefined的比较相对模糊,这里升华一下。

null是一个表示”无”的对象,转为数值时为0undefined是一个表示”无”的原始值,转为数值时为NaN。)这个性质只是在运算时才有作用,比较时不是这样的。

原因就是我们的nullundefined已经都是原始值了,即便null是一个对象,但是也是当成一个原始值了,而原始值在比较会有区分,只有undefinednull会在比较时相互转换从而在==运算符的结果中返回true

null是对象,而undefined则是一个原始数据类型,当我们typeof null时就是"object"undefined则就是"undefined"

这里又可以解释上面undefinednull,因为null是一个对象,而它又是一个原始值,那么他的转换关系javascript已经确定好了,个人无法知道它内部是怎么处理的,只知道null在和undefined比较的时候会转换为undefined

null表示的是此处不应该有值,而undefined则表示此处要有值,只是还没有赋值,这是两个表示的不同含义。

1 0
原创粉丝点击