java script中==和===_Java Script 中 ==(Equal) 和 === (Identity Equal) 的区别和比较算法逻辑...

判断两个变量是否相等在任何编程语言中都是非常重要的功能。

JavaScript 提供了 == 和 === 两种判断两个变量是否相等的运算符,但我们开始学习的时候 JavaScript 的时候,就被一遍又一遍的告知:

=== 要求变量的类型和值均相等,才能返回true。

使用 === 来避免因JavaScript 类型转换带来的问题。

这样增加了 JavaScript 语法的灵活性但是也带来很多头疼的问题:

使用 ==/!=是 ===/!== 来判断两个变量是否相等?

为什么,JS 编码推荐使用 ===/!= 而不是 ==/!=,大部分的编程语言不都是使用==/!=么?

为了要回答这个问题,让我们看一下 JavaScript 所遵守的标准 ECMAScript 对于==和 === 是怎么描述的吧!

=== 详解

Identity Equal或 Strict Equal, 在 ECMAScript -- Java Script 所遵守的标准中,算法的定义为:The Strict Equality Comparison Algorithm, 规则如下:

如果 参数 x 的数据类型和 参数 y 的数据类型不一致,这返回 false

如果 参数 x 的数据类型为 undenfined, 则返回 true

如果 参数 x 的数据类型为 null, 则返回 true

如果 参数 x 的数据类型为 Number, 则:

如果 x 是  NaN 返回 false

如果 y 是  NaN 返回 false

如果 x 是 +0 并且 y 为 -0, 返回 true

如果 x 是 -0 并且 y 为 +0, 返回 true

如果 x 和 y 有着相同的数值,返回 true

返回 false

如果 x 的类型为 String, 且 x 与 y 有着相同的顺序排列的字符串, 返回 true

如果 x 的类型为 boolean, 且 x 与 y 拥有相同的布尔值,返回 true

如果 x 的类型为 Object, 且 x 与 y 指向相同的对象,返回 true

伪代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 functionstrictEqual(x, y) {2 //If Type(x) is different from Type(y), return false.

3 if (!valueEqual(typeof (x), typeof(y))) {4 return false;5 }6

7 //If Type(x) is Undefined, return true.

8 //If Type(x) is Null, return true.

9 if (valueEqual(typeof (x), "undefined") || valueEqual(x, null)) {10 return true;11 }12

13

14 if (valueEqual(typeof (x), "number")) {15 //If x is NaN, return false.

16 if(isNaN(x)) {17 return false;18 }19

20 //If y is NaN, return false.

21 if(isNaN(y)) {22 return false;23 }24

25 //If x is +0 and y is −0, return true.

26 if (valueEqual(x, +0) && valueEqual(y, -0)) {27 return true;28 }29

30 //If x is −0 and y is +0, return true.

31 if (valueEqual(y, +0) && valueEqual(x, -0)) {32 return true;33 }34

35 //If x is the same Number value as y, return true.

36 if(valueEqual(x, y)) {37 return true;38 }39

40 return false;41 }42

43 if (valueEqual(typeof (x), "string")) {44 //If Type(x) is String, then return true if x and y are exactly

45 //the same sequence of characters

46 //(same length and same characters in corresponding positions); otherwise, return false.

47 returnhasSameChar(x, y);48 }49

50 if (valueEqual(typeof (x), "boolean")) {51 returnvalueEqual(x, y);52 }53

54 if (valueEqual(typeof (x), "object")) {55 //Return true if x and y refer to the same object. Otherwise, return false.

56 returnhasSameReference(x, y);57 }58

59 return false;60 }

View Code

逻辑图:

593707b916fac7536d2475813da8db84.png

== 详解

Equal, 在两个对比变量数据类型相同时, 和=== 有着一样的行为算法实现,但是当两个对比的变量数据类型不同时,ECMAScript/JavaScript 有着自定义的转换和比较逻辑:参考 The Abstract Equality Comparison Algorithm

如果 x 为 null, 且 y 为 undefined, 返回 true

如果 x 为 undefined, 且 y 为 null, 返回 true

如果 x 的数据类型为 Number, 且 y 的数据类型为 string, 则将 y 转换为 Number,然后进行比较

如果 x 的数据类型为 String, 且 y 的数据类型为 Number, 则将 x 转换为 Number,然后进行比较

如果 x 的数据类型为 Boolean, 将x 转换为数字类型,当 x 为 true 时转换为 1, 否则转换为 0 进行比较

如果 y 的数据类型为 Boolean, 将 y 转换为数字类型,当 y 为 true 时转换为 1, 否则转换为 0 进行比较

如果 x 的数据类型为 String 或者 Number, 且 y 为 Object, 则使用 valueOf 函数,将 y 转换为简单类型进行比较

如果 y 的数据类型为 String 或者 Number, 且 x 为 Object, 则使用 valueOf 函数,将 x 转换为简单类型进行比较

返回 false

从上述定义不难总结出以下几点:

该算法为递归算法,转换后,继续调用其自身直到能比较且返回为止

该算法依赖于 Strict Equal 的实现

进行转换时,具体转换依赖于数据类型的定义的方法,如Number() 函数

伪代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 functionabstractEqual(x, y) {2

3 //if x and y has same type

4 if (valueEqual(typeof (x), typeof(y))) {5 returnstrictEqual(x, y);6 }7

8 //If x is null and y is undefined, return true.

9 if (valueEqual(x, null) &&valueEqual(y, undefined)) {10 return true;11 }12

13 //If x is undefined and y is null, return true.

14 if (valueEqual(x, undefined) && valueEqual(y, null)) {15 return true;16 }17

18 //Type(x) is Number and Type(y) is String,

19 if (valueEqual(typeof (x), "number") && valueEqual(typeof (y), "string")) {20

21 var convertedY =Number(y);22

23 //return the result of the comparison x == ToNumber(y)

24 returnabstractEqual(x, convertedY);25 }26

27 //Type(x) is Number and Type(y) is String,

28 if (valueEqual(typeof (x), "string") && valueEqual(typeof (y), "number")) {29

30 var convertedX =Number(x);31

32 //return the result of the comparison x == ToNumber(y)

33 returnabstractEqual(convertedX, y);34 }35

36 //Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

37 if (valueEqual(typeof (x), "boolean")) {38 var convertedToIntX =Number(x);39

40 returnabstractEqual(convertedToIntX, y);41 }42

43 //Type(x) is Boolean

44 if (valueEqual(typeof (y), "boolean")) {45 var convertedToIntY =Number(y);46

47 //return the result of the comparison ToNumber(x) == y.

48 returnabstractEqual(x, convertedToIntY);49 }50

51 //If Type(x) is either String or Number and Type(y) is Object,

52 if ((valueEqual(typeof (x), "string") || valueEqual(typeof (x), "number")) && valueEqual(typeof (y), "object")) {53 var toPrimitiveY =y.valueOf();54

55 //return the result of the comparison x == ToPrimitive(y).

56 returnabstractEqual(x, toPrimitiveY);57 }58

59

60 //If Type(x) is either String or Number and Type(y) is Object,

61 if ((valueEqual(typeof (y), "string") || valueEqual(typeof (y), "number")) && valueEqual(typeof (x), "object")) {62 var toPrimitiveX =x.valueOf();63

64 //return the result of the comparison x == ToPrimitive(y).

65 returnabstractEqual(toPrimitiveX, y);66 }67

68 return false;69 }

View Code

逻辑图:

10042f1aa9eeb6885615dc85197b7f9a.png

附加上本例使用的判断相等的函数的代码,直接使用了 JavaScript 的 == 来实现,为了 demo 么!呵呵,这是一个很号的接口,实际上,我也实现不出来 :).

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 functionvalueEqual(x, y) {2 return x ===y;3 }4

5 functionhasSameChar(x, y) {6 return x ===y;7 }8

9 functionhasSameReference(x, y) {10 return x ===y;11 }

View Code

总结

现在,我们已经知道 == 和 === 在判断两个变量是否相等时所使用的算法的基本实现。帮助我们理解一些 JavaScript 中判断相等时一些"诡异“ 的行为。

把我们写的 Script 放在一个 HTML 文件里,用 Chrome 代开,按 F12, 开始我们的调试吧:

测试 JS 代码

运行结果

JS 代码

运行结果

备注

var x = 1, y = "1";console.log(strictEqual(x,y)); console.log(abstractEqual(x,y))

false, true

var x = 1, y = "1";console.log(x === y); console.log(x == y)

false,true

== 时,y 先转换为数字类型1

var x = 1, y = "not a number";console.log(strictEqual(x,y)); console.log(abstractEqual(x,y))

false, falase

var x = 1, y = "not a number";console.log(x === y); console.log(x == y)

false, false

y 转换为数字类型失败,返回 NaN,NaN 不与任何值相等,包括 NaN 自身

var x = undefined, y = null;console.log(strictEqual(x,y)); console.log(abstractEqual(x,y))

false,true

var x = undefined, y = null;console.log(x===y); console.log(x == y)

false,true

=== 时, null != undefined

== 时,规定了 null 与 undefined 的相等

var x = true, y = 2;console.log(strictEqual(x,y)); console.log(abstractEqual(x,y))

false,false

var x = true, y = 2;console.log(x === y); console.log(x == y)

false,false

true 转换为数字 1

var x = false, y = 0;console.log(strictEqual(x,y)); console.log(abstractEqual(x,y))

false,true

var x = false, y = 0;console.log(x === y); console.log(x == y)

false,true

false 转换为数字 0

var x = {name:'test',valueOf:function(){return 1;}},y = 1; console.log(strictEqual(x,y));console.log(abstractEqual(x,y));

false,true

var x = {name:'test',valueOf:function(){return 1;}},y = 1; console.log(x === y);console.log(x == y);

false,true

x.valueOf()  返回数字 1,与 y 相等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值