JavaScript相等运算符的九条规则示例详解_javascri

来源:http://www.chinese-glasses.com 作者:Web前端 人气:97 发布时间:2020-05-06
摘要:时间: 2019-09-11阅读: 81标签: 规则 简介 在日常的 JS编码过程中,可能很难看到相等运算符(=)是如何工作的。特别是当操作数具有不同类型时。这有时会在条件语句中产生一些难以识别的

时间: 2019-09-11阅读: 81标签: 规则

简介

在日常的 JS 编码过程中,可能很难看到相等运算符(=)是如何工作的。特别是当操作数具有不同类型时。这有时会在条件语句中产生一些难以识别的 bug。很容易理解为什么0 == 8是flase的或者'' == false是true。但是为什么{} == true是false的就看不出来了。接下将会讲这是肿么肥事。

Java的等号有=,==,===三个运算符虽然都读成“等于”,但概念是不一样的,=指的是赋值,在这篇文章中我们不会进行更多的介绍;==称为相等运算符,比较的是两个操作数值是否相等;===称为严格相等运算符,比较的是两个操作数是否是“同一个值”。

在这之前,先说几个术语:

针对相等运算符==和===,有两个对应的!=和!==运算符,这两个不相等运算符的运算结果是==和===运算结果的相反值。

操作符(Operator)表示操作的符号。例如,相等运算符==比较两个值,三等运算符===比较两个值及其类型,加法运算符+两个数字和或连接两个字符串。

严格相等运算符

操作数(Operand)是运算的主体,是执行运算的数量。例如,在表达式0 == {}中,0是第一个操作数,{}是第二个操作数。

严格相等运算符在对操作数进对比运算时,是不进行类型转换的。对比规则如下:

JS 中的基本数据类型(原始类型)有number,string,boolean,null和undefined,symbol。

1. 操作数类型不同

全等运算符 ===

1 === "1" // falsetrue === "true" // falseundefined === true //false1 === true //false

全等和不全等操作符遵循以下基本规则(IEA规则):

2.同一类原始类型值

如果两个操作数有不同的类型,它们不是严格相等的如果两个操作数都为null,则它们是严格相等的如果两个操作数都为undefined,它们是严格相等的如果一个或两个操作数都是NaN,它们就不是严格相等的如果两个操作数都为true或都为false,它们是严格相等的如果两个操作数都是number类型并且具有相同的值,则它们是严格相等的如果两个操作数都是string类型并且具有相同的值,则它们是严格相等的如果两个操作数都引用相同的对象或函数,则它们是严格相等的以下所有其他情况下操作数都不是严格相等的。

如果两个值都是原始类型值,值相同就返回true,值不同就返回false。

规则很简单。

对于原始类型值,要注意的是,0和-0是相等的;如果两个值是字符串,需要它们在16位编码的相同位置上有相同的值才是相等。如果是不同的16位编码序列,就算有相同的内容,相同的长度,结果也是不相等。

值得一提的是,在全等运算中,NaN与其他任何值相比,结果都是false。 来看看考虑些例子,这是学习这些规则的好方式。

'1' === '0' //false1 === 0x1 // true

例 1

3.同是对象

1 === "1" // false, 规则 1

如果两个值是对象,对于两个对象比较的是引用,如果引用指向的是不同的对象,则结果是不相等。

操作数是不同的类型(数字和字符串),基于 IEA 规则1,它们是不等的。

{} === {} // false[] === [] // false {} === function  // falsevar v1 = {};var v2 = v1; //v2和v1指向同一个引用地址v1 === v2 // true // 没有参数的情况let s1 = Symbol;s1 === s2 // false// 有参数的情况let s1 = Symbol;let s2 = Symbol;let s3 = s1;s1 === s2 // falses1 === s2 // true

例 2

4. null和undefined

0 === 0 // true, 规则 6

如果两个值都是null或者都是undefined,结果是true

操作数具有相同的类型和相同的值,因此根据IEA规则6,它们是严格相等的。

null === null //trueundefined === undefined //true

例 3

5.NaN

undefined === undefined // true, 规则 3

如果两个值都是NaN,结果是false

两个操作数都是undefined的,应用 IEA 规则3,它们是相等的。

NAN === NAN //false

例 4

NaN和任何数字都不相等,包括它自身

undefined === null // false, 规则 1

相等运算符

因为操作数是不同的类型,根据IEA规则1,它们并不相同。

1. 值的类型相同

例 5

应用严格相等运算符转换规则的值类型相同规则。

NaN === NaN // false, IEA 规则 5

2.不同原始类型值

操作数是相同的类型,但是IEA 规则4 表明任何与 NaN 比较都是不相等的。

如果是不同原始类型值进行比较,将非数字类型转换成数字,再进行比较。

例 6

0 == undefined //false// 等同于 0 == Number// 等同于0 == NAN0 == null //false// 等同于 0 == Number1 == true // true// 等同于 1 == Number'true' == true // false// 等同于 Number == Number// 等同于 NaN === 1'' == 0 // true// 等同于 Number == 0// 等同于 0 == 0'1' == true // true// 等同于 Number// 等同于 1 == 1'n 123 t' == 123 // true// 因为字符串转为数字时,省略前置和后置的空格
var firstObject = {}, secondObject = firstObject;secondObject['name'] = 'Neo';secondObject === firstObject // true, IEA 规则 8

3. 对象和原始类型值

两个变量firstObject和secondObject都是对同一对象的引用,根据 IEA 规则8,它们相等。

如果其中一个操作数是对象,另外一个是原始类型值,按如下规则转:

例 7

将对象转换成原始类型值 转换后的原始类型值与另一个操作数的类型一样,使用值类型相同的规则 如果不一样,将非数字类型转换成数字再进行比较。

[] === [] //false, IEA 规则 9
[1] == 1 //true

字面量[]创建了一个新的数组引用。这两个操作数是相同的类型(对象),但是它们引用不同的对象。根据 IEA 规则 9 ,它们不相等。

a. [1]先转换成原始值"1";

对象转换为原始值的规则

b. 转换后与右边的操作数1类型不一样,将"1"转换成1;

对象到布尔值

c. 1 == 1 结果是true

对象到布尔值的转换非常简单:所有的对象(包括数字和函数)都转换为true。对于包装对象亦是如此:new Boolean(false)是一个对象而不是原始值,它将转换为true。

[1] == "1"

对象到字符串

a. [1]先转换成原始值"1";

对象到字符串对象到数字的转换都是通过调用待转换对象的一个方法来完成的。一个麻烦的事实是,JS 对象有两个不同的方法来执行转换,接下来要讨论的一些特殊场景更加复杂。值得注意的是,这里提到的字符串和对象的转换规则只适用于原生对象(native object)。宿主对象(例如有Web浏览器定义的对象)根据各自的算法可以转换成字符串和数字。

b. 转换后与右边的操作数"1"类型一样,"1"=="1",结果是true;

所有的对象继承了两个转换方法。第一个是toString(),它的作用是返回一个反映这个对象的字符串。默认的toString()方法并不会返回一个有趣的值:

[1] == true
({x:1,y:2}).toString() //="[object object]"

a. [1]先转换成原始值"1";

很多类定义了更多特定版本的toString()方法。例如,数组的toString()方法是将每个数组元素转换为一个字符串,并在元素之间添加逗号后合并成结果字符串。

b. 转换后与右边的操作数true类型不一样,将右边的操作数true转换成1;

函数的toString()方法返回了这个函数的实现定义。实际上,这里的实现是通常是将用户定义的函数转换为 JS 源代码字符串。

c. 1 == 1结果是true

日期Date的toString()方法返回了一个可读的日期和时间字符串。

4. null和undefined

RegExp的toString()方法将RegExp对象转换为表示正则表达式直接量的字符串:

如果其中一个值是null,另外一个是undefined,结果是相等

来几个例子:

null == undefined
[1,2,3].toString() //= "1,2,3"(function(x){ f(x); }).toString() // = "function(x){ f(x); }"/d+/g.toString() // = "/d+/g"new Date(2019,9,16).toString() //= "Wed Oct 16 2019 00:00:00 GMT+0800 (中国标准时间)"

对象转换为原始类型规则

另一个转换对象的函数是valueOf()。如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单地返回对象本身,而不是返回一个原始值。数组、函数和正则表达式简单地继承了这个方法,调用这些类型的实例的valueOf()方法只是简单返回对象本身。日期Date的valueOf()方法会返回它的一个内部表示:1970年1月1日以来的毫秒数。

比较操作符的操作数可能是任意类型,然而只有数字和字符串才能真正执行比较操作,因此那些不是数字和字符串的类型都将进行类型转换。转换的规则如下:

本文由10bet发布于Web前端,转载请注明出处:JavaScript相等运算符的九条规则示例详解_javascri

关键词:

最火资讯