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

伪代码:

64f4fb77159880ff721c60d447a7ad12.gif

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

逻辑图:

34190cc59f0c98e3b0ac3c810b7b9d93.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() 函数

伪代码:

64f4fb77159880ff721c60d447a7ad12.gif

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

逻辑图:

35292a3bb7027a716929f3656be651d8.png

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

64f4fb77159880ff721c60d447a7ad12.gif

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 相等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/526695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java android 数组_Android开发基础之Java 数组

Java 数组数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中提供的数组是用来存储固定大小的同类型元素。你可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0&…

bellman ford java_Java C 实现Bellman-ford算法

package com.cn.tree;public class MyException extends Exception {private static final long serialVersionUID 1L;public MyException(String str) {super(str);}public MyException() {}}package com.cn.graph;import com.cn.tree.MyException;/*** 很明显时间复杂度为O(…

c#模拟看板控件_在Winform界面使用自定义用户控件及TabelPanel和StackPanel布局控件...

在很多时候,我们做一些非常规化的界面的时候,往往需要创建一些用户控件,在其中绘制好一些基础的界面块,作为后续重复使用的一个单元,用户控件同时也可以封装处理一些简单的逻辑。在开发Winform各种类型项目&#xff0c…

java jdbc 详解_JDBC概述及详解各个对象

JDBC(Java DataBase Connectivity)详解一.概念:JDBC是一种可执行SQL语句的JavaAPI,Java数据库链接,Java语言操做数据库mysql二.本质:JDBC是一种可用于执行SQL语句的Java API,由一些Java语言编写的类和页面组成。各个数…

java空心字木塔_我国七个千年古塔:第四个空心没有塔顶,最后一个是木塔无钉无铆...

1、崇圣寺三塔,云南大理,公元824—839年崇圣寺三塔是一个三塔三阁组成的建筑群,最大的主塔又名千寻塔。是中国现存层数最多的古佛塔,拥有16层。崇圣寺三塔历经30多次地震不倒,极其顽强。2、大雁塔,陕西西安…

java8 ie_Java8语法糖之Lambda表达式_Hudie.的博客-CSDN博客

原文作者:编程一只蝶原文标题:Java8语法糖之Lambda表达式发布时间:2021-02-16 13:08:40一、Lambda表达式简介Lambda表达式,是Java8的一个新特性,也是Java8中最值得学习的新特性之一。(另一个新特性是流式编程。)Lambda…

python中的event_Python event

最新项目游戏感用于SteelSeries GameSense 3.8.x的Python库安装这个包有两个不同的版本。一个支持普通的同步函数调用,另一个支持python的异步功能。要安装同步版本,请运 ...2021-03-02已阅读: n次此模块验证事件模块中的电话号码,就像base_p…

centos的mysql怎么删用户_linux/centos给Mysql创建用户、授权、查看、删除、修改密码、撤...

linux/centos给Mysql创建用户、授权、查看、删除、修改密码、撤linux/centos给Mysql创建用户、授权、查看、删除、修改密码、撤销权限linux/centos给Mysql创建用户、授权、查看、删除、修改密码、撤销权限root权限高,安全性考虑,一般只允许本地(本机)访问…

采取 过滤 php_这3种php高级过滤了解一下,很实用!

在php中有很多的过滤,可以对输入的字符串进行过滤,同时也可以对邮件地址进行过滤,接下来我要讲的是php中的3种高级过滤,在开发中很实用。第一种:过滤数值范围在php经常要接收各种数据,其中数值是非常普遍的…

吃PHP小孩智力好,这7种鱼千万不能给孩子吃,会影响孩子的智力!

所以,给宝宝添加鱼类时一定要注意,有7种鱼含有大量金属元素,是千万不能给宝宝吃的!1罗非鱼罗非鱼深青色的外表有几分像鲫鱼。由于罗非鱼的成长周期较长,它们体内汞的含量也就相比其他鱼偏高,小朋友吃罗非鱼…

java监控rabbitMq服务状态,spring cloud 的监控turbine-rabbitmq的示例

前提是你已经有了注册中心,然后搭建一个基础spring cloud 服务,并配置注册服务等等前提环境搭建接下来描述的服务提供者和服务调用者的配置都是一样的,来自《spring cloud 与 docker微服务架构实战》的读后的个人总结.pom文件中需要引入spring-cloud-starter-hystrix/spring-cl…

java弹球轨迹运动解说,动态弹球的实现 加入了多线程技术-javaSE游戏准备工作

动态弹球的实现 加入了多线程技术--javaSE游戏准备工作任务描述:实现了动态弹球的功能,对于有弹球功能的SE游戏奠定了基础。package 运用线程技术的小球;import java.awt.*;import java.awt.event.*;import java.awt.geom.*;//不清楚这个有什么用import java.util.*…

asp php 用户登录,一个简单的asp.net 单点登录实现

以下是实现的效果图:首先上图的点击火车订票链接,就会打开http://学生信息平台网站/LoginToTrainSite.asa页面。LoginToTrainSite.asa页面的大致代码如下:Response.Buffer TrueResponse.ExpiresAbsolute Now() - 1Response.Expires 0Respo…

ajax怎么发送数据给php,ajax怎么发送数据给php

在网上看了很久,发现数据的利用ajax提交数据到后台其实很简单,但是很多讲解的并不清楚,对于初学者来说,很多真的是看着有点糊涂,拿来直接用,又想去了解怎么回事,其实利用ajax提交数据到后台是非…

oracle10无法安装打开,64位win10添加oracle odbc驱动时提示无法加载oracle怎么办

对于win10 64位系统添加oracle odbc驱动时提示无法加载oracle的问题相信部分用户都应该有所了解了,但是对于如何解决这个问题的实际操作的用户来说可能不多,因此,为了帮助出现这种问题的用户,小编在这里就来教大家64位win10添加or…

linux postgresql默认安装目录,postgresql - 三种安装方式(示例代码)

最近接触了postgresql的安装,和大家分享一下。一、简 介PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS),也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统。有些特性甚至连商业数据库都不具备。这个起源于伯克利(…

linux中央服务器,如何在Linux上搭建一个Git中央仓库

前言:本教程只面向那些个人开发者,想要自己在linux上搭建一个git中央仓库用来上传发布自己的项目。但是对于团队来说可能有更高的要求,可以使用gitlab搭建一个可视化的类似github的版本管理系统测试环境我使用的linux版本是Centos7&#xff0…

linux桌面发展方向,观点|Linux 桌面的发展之路!

Ken Starks 在 fossforce.com 网站上问 你们是如何优化 Linux 的?,我很高兴他问了这个问题,因为我有话要说!对我来说,Linux 桌面就是一连串的承诺,但是这些承诺却总是无法兑现。它在每个版本发布后都会说“…

linux常见基础服务,常用的linux命令的基本使用(一)

序号命令对应英文作用01lslist查看当前文件夹下的内容02pwdprint name of of current/working directory查看当前所在文件夹03cd[目录名]change directory切换文件夹04touch[目录名]touch如果文件不存在,新建文件05mkdir[目录名]make directory创建目录06rm[文件名]…

树莓派怎么学linux,树莓派使用入门用树莓派学 Linux

树莓派使用入门用树莓派学 Linux我们的《树莓派使用入门》的第四篇文章将进入到 Linux 命令行。在本系列的 第三篇文章 中开始了我们的树莓派探索之旅,我分享了如何安装 Raspbian,它是树莓派的官方 Linux 版本。现在,你已经安装好了 Raspbian…