9月阅读周·JavaScript权威指南:表达式和运算符,关系表达式篇

举报
叶一一 发表于 2024/09/23 10:06:20 2024/09/23
【摘要】 背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。这个“玩法”虽然常见且板正,但是有效,已经坚持阅读八个月。已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScri...

背景

去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。

没有计划的阅读,收效甚微。

新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。

这个“玩法”虽然常见且板正,但是有效,已经坚持阅读八个月。

已读完书籍《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》

当前阅读周书籍《JavaScript权威指南》

关系表达式

相等和不等运算符

“==”和“===”运算符用于比较两个值是否相等,当然它们对相等的定义不尽相同。两个运算符允许任意类型的操作数,如果操作数相等则返回true,否则返回false。“===”也称为严格相等运算符(strict equality)(有时也称做恒等运算符(identity operator)),它用来检测两个操作数是否严格相等。“==”运算符称做相等运算符(equality operator),它用来检测两个操作数是否相等,这里“相等”的定义非常宽松,可以允许进行类型转换。

JavaScript支持“=”、“==”和“===”运算符。你应当理解这些(赋值、相等、恒等)运算符之间的区别,并在编码过程中小心使用。尽管它们都可以称做“相等”,但为了减少概念混淆,应该把“=”称做“得到或赋值”,把“==”称做“相等”,把“===”称做“严格相等”。

“!=”和“!==”运算符的检测规则是“==”和“===”运算符的求反。如果两个值通过“==”的比较结果为true,那么通过“!=”的比较结果则为false。如果两值通过“===”的比较结果为true,那么通过“!==”的比较结果则为false。4.10节会提到,“!”运算符是布尔非运算符。我们只要记住“!=”称做“不相等”、“!==”称做“不严格相等”就可以了。

JavaScript对象的比较是引用的比较,而不是值的比较。对象和其本身是相等的,但和其他任何对象都不相等。如果两个不同的对象具有相同数量的属性,相同的属性名和值,它们依然是不相等的。相应位置的数组元素是相等的两个数组也是不相等的。

严格相等运算符“===”首先计算其操作数的值,然后比较这两个值,比较过程没有任何类型转换:

  • 如果两个值类型不相同,则它们不相等。
  • 如果两个值都是null或者都是undefined,则它们不相等。
  • 如果两个值都是布尔值true或都是布尔值false,则它们相等。
  • 如果其中一个值是NaN,或者两个值都是NaN,则它们不相等。NaN和其他任何值都是不相等的,包括它本身!通过x!==x来判断x是否为NaN,只有在x为NaN的时候,这个表达式的值才为true。
  • 如果两个值为数字且数值相等,则它们相等。如果一个值为0,另一个值为-0,则它们同样相等。
  • 如果两个值为字符串,且所含的对应位上的16位数完全相等,则它们相等。如果它们的长度或内容不同,则它们不等。两个字符串可能含义完全一样且所显示出的字符也一样,但具有不同编码的16位值。JavaScript并不对Unicode进行标准化的转换,因此像这样的字符串通过“===”和“==”运算符的比较结果也不相等。第三部分的String.localeCompare()提供了另外一种比较字符串的方法。
  • 如果两个引用值指向同一个对象、数组或函数,则它们是相等的。如果指向不同的对象,则它们是不等的,尽管两个对象具有完全一样的属性。

相等运算符“==”和恒等运算符相似,但相等运算符的比较并不严格。如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较:

  • 如果两个操作数的类型相同,则和上文所述的严格相等的比较规则一样。如果严格相等,那么比较结果为相等。如果它们不严格相等,则比较结果为不相等。
  • 如果两个操作数类型不同,“==”相等操作符也可能会认为它们相等。检测相等将会遵守如下规则和类型转换:
    • 如果一个值是null,另一个是undefined,则它们相等。
    • 如果一个值是数字,另一个是字符串,先将字符串转换为数字,然后使用转换后的值进行比较。
    • 如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,则将其转换为0再进行比较。
    • 如果一个值是对象,另一个值是数字或字符串,则使用转换规则将对象转换为原始值,然后再进行比较。对象通过toString()方法或者valueOf()方法转换为原始值。JavaScript语言核心的内置类首先尝试使用valueOf(),再尝试使用toString(),除了日期类,日期类只使用toString()转换。那些不是JavaScript语言核心中的对象则通过各自的实现中定义的方法转换为原始值。—其他不同类型之间的比较均不相等。

这里有一个判断相等的小例子:

  "1"==true

这个表达式的结果是true,这表明完全不同类型的值比较结果为相等。布尔值true首先转换为数字1,然后再执行比较。接下来,字符串“1”也转换为了数字1,因为两个数字的值相等,因此比较结果为true。

比较运算符

比较运算符用来检测两个操作数的大小关系(数值大小或者字母表的顺序):

小于(<)

如果第一个操作数小于第二个操作数,则“<”运算符的计算结果为true;否则为false。

大于(>)

如果第一个操作数大于第二个操作数,则“>”运算符的计算结果为true;否则为false。

小于等于(<=)

如果第一个操作数小于或者等于第二个操作数,则“<=”运算符的计算结果为true;否则为false。

大于等于(>=)

如果第一个操作数大于或者等于第二个操作数,则“>=”运算符的计算结果为false;否则为false。

in运算符

in运算符希望它的左操作数是一个字符串或可以转换为字符串,希望它的右操作数是一个对象。如果右侧的对象拥有一个名为左操作数值的属性名,那么表达式返回true,例如:

  var point={x:1,y:1};//定义一个对象
  "x"in point//=>true:对象有一个名为"x"的属性
  "z"in point//=>false:对象中不存在名为"z"的属性
  "toString"in point//=>true:对象继承了toString()方法
  var data=[7,8,9];//拥有三个元素的数组
  "0"in data//=>true:数组包含元素"0"
  1 in data//=>true:数字转换为字符串
  3 in data//=>false:没有索引为3的元素

instanceof运算符

instanceof运算符希望左操作数是一个对象,右操作数标识对象的类。如果左侧的对象是右侧类的实例,则表达式返回true;否则返回false。第9章将会讲到,JavaScript中对象的类是通过初始化它们的构造函数来定义的。这样的话,instanceof的右操作数应当是一个函数。比如:

  var d=new Date();//通过Date()构造函数来创建一个新对象
  d instanceof Date;//计算结果为true,d是由Date()创建的
  d instanceof Object;//计算结果为true,所有的对象都是Object的实例
  d instanceof Number;//计算结果为false,d不是一个Number对象
  var a=[1,2,3];//通过数组直接量的写法创建一个数组
  a instanceof Array;//计算结果为true,a是一个数组
  a instanceof Object;//计算结果为true,所有的数组都是对象
  a instanceof RegExp;//计算结果为false,数组不是正则表达式

需要注意的是,所有的对象都是Object的实例。当通过instanceof判断一个对象是否是一个类的实例的时候,这个判断也会包含对“父类”(superclass)的检测。如果instanceof的左操作数不是对象的话,instanceof返回false。如果右操作数不是函数,则抛出一个类型错误异常。

为了理解instanceof运算符是如何工作的,必须首先理解“原型链”(prototype chain)。原型链作为JavaScript的继承机制,将在6.2.2节详细讲述。为了计算表达式o instanceof f,JavaScript首先计算f.prototype,然后在原型链中查找o,如果找到,那么o是f(或者f的父类)的一个实例,表达式返回true。如果f.prototype不在o的原型链中的话,那么o就不是f的实例,instanceof返回false。

总结

关系运算符用于测试两个值之间的关系(比如“相等”,“小于”,或“是...的属性”),根据关系是否存在而返回true或false。关系表达式总是返回一个布尔值,通常在if、while或者for语句(参照第5章)中使用关系表达式,用以控制程序的执行流程。接下来的几节将会讲述相等和不等运算符、比较运算符和JavaScript中其他两个关系运算符in和instanceof。


作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。