《JavaScript高级程序设计》(第4版)阅读笔记(十五)

这篇文章继续讲《高程四》的第三章的内容。

3.5.4 乘性操作符
 

ECMAScript定义了3个乘性操作符:乘法、除法和取模。这些操作符跟它们在Java、C语言及Perl中对应的操作符作用一样,但在处理非数值时,它们也会包含一些自动的类型转换。如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用 Number() 转型函数转换为数值。这意味着空字符串会被当成0,而布尔值 true 会被当成1

 

1. 乘法操作符
 

乘法操作符由一个星号( * )表示,可以用于计算两个数值的乘积。
乘法操作符在处理特殊值时也有一些特殊的行为。

如果操作数都是数值,则执行常规的乘法运算,即两个正值相乘是正值,两个负值相乘也是正值,正负符号不同的值相乘得到负值。如果ECMAScript不能表示乘积,则返回Infinity 或 -Infinity 。
如果有任一操作数是 NaN ,则返回 NaN 。
如果是 Infinity 乘以0,则返回 NaN 。
如果是 Infinity 乘以非0的有限数值,则根据第二个操作数的符号返回 Infinity 或 -Infinity 。
如果是 Infinity 乘以 Infinity ,则返回Infinity 。
如果有不是数值的操作数,则先在后台用 Number() 将其转换为数值,然后再应用上述规则。

2. 除法操作符

除法操作符由一个斜杠( / )表示,用于计算第一个操作数除以第二个操作数的商。跟乘法操作符一样,除法操作符针对特殊值也有一些特殊的行为。

如果操作数都是数值,则执行常规的除法运算,即两个正值相除是正值,两个负值相除也是正值,符号不同的值相除得到负值。如果ECMAScript不能表示商,则返回 Infinity
或 -Infinity 。

如果有任一操作数是 NaN ,则返回 NaN 。
如果是 Infinity 除以 Infinity ,则返回 NaN 。
如果是0除以0,则返回 NaN 。
如果是非0的有限值除以0,则根据第一个操作数的符号返回Infinity 或 -Infinity 。
如果是 Infinity 除以任何数值,则根据第二个操作数的符号返回 Infinity 或 -Infinity 。
如果有不是数值的操作数,则先在后台用 Number() 函数将其转换为数值,然后再应用上述规则。

3. 取模操作符

取模(余数)操作符由一个百分比符号( % )表示。

与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为。

如果操作数是数值,则执行常规除法运算,返回余数。
如果被除数是无限值,除数是有限值,则返回 NaN 。
如果被除数是有限值,除数是0,则返回 NaN 。
如果是 Infinity 除以 Infinity ,则返回 NaN 。
如果被除数是有限值,除数是无限值,则返回被除数。
如果被除数是0,除数不是0,则返回0。
如果有不是数值的操作数,则先在后台用 Number() 函数将其转换为数值,然后再应用上述规则。

3.5.5 指数操作符
 

ECMAScript 7新增了指数操作符, Math.pow() 现在有了自己的操作符 ** ,结果是一样的:

console.log(Math.pow(3, 2); // 9
console.log(3 ** 2); // 9
console.log(Math.pow(16, 0.5); // 4
console.log(16 ** 0.5); // 4

不仅如此,指数操作符也有自己的指数赋值操作符 **= ,该操作符执行指数运算和结果的赋值操作:

let squared = 3;
squared **= 2;
console.log(squared); // 9
let sqrt = 16;
sqrt **= 0.5;
console.log(sqrt); // 4

3.5.6 加性操作符

加性操作符,即加法和减法操作符,一般都是编程语言中最简单的操作符。不过,在ECMAScript中,这两个操作符拥有一些特殊的行为。与乘性操作符类似,加性操作符在后台会发生不同数据类型的转换。只不过对这两个操作符来说,转换规则不是那么直观。

 

1. 加法操作符
 

加法操作符( + )用于求两个数的和。

如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:

如果有任一操作数是 NaN ,则返回 NaN ;
如果是 Infinity 加 Infinity ,则返回 Infinity ;
如果是 -Infinity 加 -Infinity ,则返回 -Infinity ;
如果是 Infinity 加 -Infinity ,则返回 NaN ;
如果是 +0 加 +0 ,则返回 +0 ;
如果是 -0 加 +0 ,则返回 +0 ;
如果是 -0 加 -0 ,则返回 -0

不过,如果有一个操作数是字符串,则要应用如下规则

如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面;
如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起。

如果有任一操作数是对象、数值或布尔值,则调用它们的toString() 方法以获取字符串,然后再应用前面的关于字符串的规则。对于 undefined 和 null ,则调用 String() 函数,分别获取 "undefined" 和 "null" 。

let result1 = 5 + 5; // 两个数值
console.log(result1); // 10
let result2 = 5 + "5"; // 一个数值和一个字符串
console.log(result2); // "55"

ECMAScript中最常犯的一个错误,就是忽略加法操作中涉及的数据类型。(下面的例子是混加了数字和字符串,如果要得到正确的结果,需要在num1+num2的外层包裹括号。

这是因为每次加法运算都是独立完成的。第一次加法的操作数是一个字符串和一个数值(5),结果还是一个字符串。第二次加法仍然是用一个字符串去加一个数值(10),同样也会到一个字符串。

let num1 = 5;
let num2 = 10;
let message = "The sum of 5 and 10 is " + num1 + num2;
console.log(message); // "The sum of 5 and 10 is 510"

2. 减法操作符

减法操作符( - )也是使用很频繁的一种操作符。

与加法操作符一样,减法操作符也有一组规则用于处理ECMAScript中不同类型之间的转换

如果两个操作数都是数值,则执行数学减法运算并返回结果。
如果有任一操作数是 NaN ,则返回 NaN 。
如果是 Infinity 减 Infinity ,则返回 NaN 。
如果是 -Infinity 减 -Infinity ,则返回 NaN 。
如果是 Infinity 减 -Infinity ,则返回 Infinity 。
如果是 -Infinity 减 Infinity ,则返回 -Infinity 。
如果是 +0 减 +0 ,则返回 +0 。
如果是 +0 减 -0 ,则返回 -0 。
如果是 -0 减 -0 ,则返回 +0 。
如果有任一操作数是字符串、布尔值、 null 或undefined ,则先在后台使用 Number() 将其转换为数值,然后再根据前面的规则执行数学运算。如果转换结果是NaN ,则减法计算的结果是 NaN 。
如果有任一操作数是对象,则调用其 valueOf() 方法取得表示它的数值。如果该值是 NaN ,则减法计算的结果是NaN 。如果对象没有 valueOf() 方法,则调用其toString() 方法,然后再将得到的字符串转换为数值。

let result1 = 5 - true; // true被转换为1,所以结果是4
let result2 = NaN - 1; // NaN
let result3 = 5 - 3; // 2
let result4 = 5 - ""; // ""被转换为0,所以结果是5
let result5 = 5 - "2"; // "2"被转换为2,所以结果是3
let result6 = 5 - null; // null被转换为0,所以结果是5

 3.5.7 关系操作符

关系操作符执行比较两个值的操作,包括小于( < )、大于( > )、小于等于( <= )和大于等于( >= ),用法跟数学课上学的一样。这几个操作符都返回布尔值

与ECMAScript中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。

如果操作数都是数值,则执行数值比较。
如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
如果有任一操作数是对象,则调用其 valueOf() 方法,取得结果后再根据前面的规则执行比较。如果没有 valueOf() 操作符,则调用 toString() 方法,取得结果后再根据前面的规则
执行比较。
如果有任一操作数是布尔值,则将其转换为数值再执行比较。

在使用关系操作符比较两个字符串时,会发生一个有趣的现象。很多人认为小于意味着“字母顺序靠前”,而大于意味着“字母顺序靠后”,实际上不是这么回事。对字符串而言,关系操作符会比较字符串中对应字符的编码,而这些编码是数值。比较完之后,会返回布尔值。问题的关键在于,大写字母的编码都小于小写字母的编码要得到确实按字母顺序比较的结果,就必须把两者都转换为相同的大小写形式(全大写或全小写),然后再比较。
 

需要注意的是,对两个数字字符串比较,得到的结果可能不正确,想要得到更准确的结果,可以用数字字符串与真正的数字进行比较。NaN与数字比较,既不会大于它,也不会小于等于它。

let result1 = NaN < 3; // false
let result2 = NaN >= 3; // false

在大多数比较的场景中,如果一个值不小于另一个值,那就一定大于或等于它。但在比较 NaN 时,无论是小于还是大于等于,比较的结果都会返回 false 。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值