Javascript中笼统相称比较算法
undefined==null
//true
[]==[]
//false
[]==![]
//true
{}==!{}
//false
![]=={}
//false
[]==!{}
//true
[1,2]==![1]
//false
大抵引见一下JS的数据范例
ES5的数据范例分为6种:Undefined
Null
String
Number
Boolean
Object
,假如再加上ES6Symbol
数据范例,一共7种;
null
与undefined
的区分:
-
null
形貌一个空值(空的对象援用即空指针),null
被当作一个对象,typeOf null
输出为'Object'
(算是一个bug吧),Number(null)
输出为0
。undefined
是预定义的全局变量,示意“缺乏值”,typeOf undefined
输出为'undefined'
,Number(undefined)
输出为NaN
; -
null
是一个关键字,而undefined
并非一个关键字;
原始值观点
js的数据范例实在能够分为两种:原始范例
和援用范例
。原始范例
又称简朴范例
和基础范例
,包含Undefined
、Null
、Boolean
、Number
和String
五种。援用范例
又称庞杂范例
,即Object
;原始范例
和援用范例
离别称为原始值
和庞杂值
;
简朴的说:原始值
是牢固而简朴的值,是存放在栈(stack)中的简朴数据段,也就是说,它们的值直接存储在变量接见的位置,原始范例
的值被称为原始值
原始范例(primitive type)
有以下五种范例:Undefined
,Null
,Boolean
,Number
,String
typeOf
运算符:
前提 | 返回值 |
---|---|
假如变量是undefined 范例 | undefined |
假如变量是Boolean 范例 | boolean |
假如变量是Number 范例 | number |
假如变量是String 范例 | string |
假如变量是Null 范例 | object |
假如变量是援用范例 | object |
笼统相称算法
用Type(z)代表z的数据范例,比较运算 x==y,个中x和y是值,发生true或false。
1.Type(x)与Type(y)雷同:
a.假如Type(x)为Undefined或Null,则返回true
b.假如Type(x)为Number,则:
i.若x为NaN,返回false
ii.若y为NaN,返回false
iii.若x与y数值相称,返回true
iiii.若x为+0,y为-0,返回true
iv.若x为-0,y为+0,返回true
v.返回false
c.假如Type(x)为String,则x和y对应位置的字符完整一样才返回true,不然返回false,
d.假如Type(x)为Boolean,则雷同值返回true,不然false
f.当x和y援用统一对象时,返回true,不然,返回false
2.x为undefined,y为null,返回true,反之亦然
3. Type(x)为String,Type(y)为Number,则返回比较ToNumber(x) == y,反之亦然
4.Type(x)为Boolean,则返回比较ToNumber(x)==y的效果,反之亦然
5.Type(x)为String或Number,Type(y)为Object,则返回比较ToPrimitive(y) == x
6.返回false
再来看看ToBoolean
,ToNumber
,ToPrimitive
三个运算符的定义:
ToBoolean
输入范例 | 效果 |
---|---|
Undefined | false |
Null | false |
Boolean | 不转换 |
Number | 假如参数是-0 ,+0 或NaN ,效果为false ,不然为true |
String | 假如参数是空字符串(长度为零),效果为false ,不然为true |
Object | true |
ToNumber
输入范例 | 效果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | 参数为true ,效果为1 ,参数为false ,效果为+0 |
Number | 不转换 |
String | 拜见下文的文法和诠释 |
Object | 运用下步骤:1、设原始值为ToPrimitive(输入参数,暗示,数值范例)。2、返回ToNumber(原始值) |
ToPrimitive
ToPrimitive运算符吸收一个值,和一个可选的希冀范例作参数。ToPrimitive运算符把其值参数转换为非范例对象。假如对象有才能被转换为不止一种原语范例,能够运用可选的 希冀范例 来暗示谁人范例。
输入范例 | 效果 |
---|---|
Undefined | 不转换 |
Null | 不转换 |
Boolean | 不转换 |
Number | 不转换 |
String | 不转换 |
Object | 返回该对象的默认值。对象的默认值由希冀范例传入作为hint 参数挪用对象内部要领[DefaultValue]获得 |
** ToPrimitive
这个要领,参照火狐MDN上的文档引见,大抵意义以下:
ToPrimitive(obj,preferredType)
JS引擎内部转换为原始值ToPrimitive(obj,preferredType)函数接收两个参数,第一个obj为被转换的对象,第二个
preferredType为愿望转换成的范例(默以为空,接收的值为Number或String)在实行ToPrimitive(obj,preferredType)时假如第二个参数为空而且obj为Date的实例时,此时preferredType会
被设置为String,其他情况下preferredType都会被设置为Number假如preferredType为Number,ToPrimitive执
行历程如
下:
- 假如obj为原始值,直接返回;
- 不然挪用 obj.valueOf(),假如实行效果是原始值,返回之;
- 不然挪用 obj.toString(),假如实行效果是原始值,返回之;
- 不然抛非常。
假如preferredType为String,将上面的第2步和第3步换取,即:
- 假如obj为原始值,直接返回;
- 不然挪用 obj.toString(),假如实行效果是原始值,返回之;
- 不然挪用 obj.valueOf(),假如实行效果是原始值,返回之;
- 不然抛非常
Ok,到现在,我们须要相识,toString
要领和valueOf
要领;
toString
用来返回对象的字符串示意。
let obj = {name:"Tom"}; //"[object Object]"
let obj = {}; //"[object Object]"
let arr = [1,2]; //"1,2"
let arr = []; //""
let str = "1"; //"1"
let num = 1; //"1"
let boo = true; //"true"
let date = new Date(); //"date Sat Mar 24 2018 00:23:12 GMT+0800 (CST)"
let nul = null; //报错
let und; //报错
valueOf
要领返回对象的原始值,多是字符串
、数值
或bool
值等,看详细的对象。
let obj = {name:"Tom"}; //{name:"Tom"}
let arr = [1,2]; //[1,2]
let str = "1"; //"1"
let num = 1; //1
let boo = true; //true
let date = new Date(); //1521822331609
let nul = null; //报错
let und; //报错
简朴明白:原始值指的是[Null
,Undefined
,String
,Boolean
,Number
]五种基础数据范例之一
总结一下==
运算的划定规矩:
1. undefined == null,效果是true。且它俩与一切其他值比较的效果都是false。
2. String == Boolean,须要两个操作数同时转为Number。
3. String/Boolean == Number,须要String/Boolean转为Number。
4. Object == Primitive(原始值),须要Object转为Primitive(详细经由过程valueOf和toString要领)。
栗子
undefined==null
//true
[]==[]
//false
[]==![]
//true
{}==!{}
//false
![]=={}
//false
[]==!{}
//true
[1,2]==![1]
//false
undefined==null
效果为true,不必诠释了,记着就好了
[]==[]
- 先看这两个的范例,
typeOf([])
获得的是'object'
- 笼统相称算法
1-f
,援用统一范例的才算相称 - 返回
false
[]==![]
-
!
取反运算符的优先级高于==
,因而先算出![]
这个得值,再去运用笼统相称算法举行比较 - 取反运算符会先挪用要领
ToBoolean
,再去取反 -
ToBoolean([])
返回的是true
,因而![]
应该为false
-
[]==![]
转换为了[]==false
- 依据笼统相称算法
4
条,则我们能够比较[]==ToNumber[false]
的值,则能够获得[]==0
- 再依据笼统相称算法
5
条,比较ToPrimitive([])==0
- 因为
[]
不是Date
范例,所以先获得[].valueOf()
的值,为[]
- 再获得
[].toString()
的值,为""
的字符串 - 以上7,8部可合并为一步即比较
[].valueOf().toString()
,获得""
字符串,此时[]
转换为了原始值范例(即五种基础范例中的一种)了。 - 依据笼统相称算法
3
,则能够比较ToNumber("")==0
,到这里[]==![]
转化为了0==0
- 返回
true
{}==![]
- 表达式右边,反复上一次的
1-5
步,能够获得{}==0
- 依据笼统相称算法
5
条,ToPrimitive({})==0
,获得{}.valueOf().toString()
获得一个字符串"[object Object]"
,是原始范例 - 依据笼统相称算法
3
,末了比较ToNumber("[object Object]")==0
,转变为1==0
- 返回
false
…
其他的栗子本身算一算吧
结语
本身从新写了写一遍整理了一下思绪,假如什么地方没有讲清楚,请指出;
参考: