Menu Close

javascript 基本运算符 – 数学运算符

数学是生活的基本组成部分,我们离不了它。尤其如此,当我们学习编写 JavaScript 程序(或任何其他语言),我们所做的很多事情都依赖于处理数值数据,计算新值等。你将不会惊讶地认识到 JavaScript 有一套可用的全功能的数学功能。

本文仅讨论你现在需要了解的基本部分。

术语:“一元”(unary)、“二元”(binary)、“操作数”(operand)

在继续之前,我们先了解一些常见术语。

  • 操作数(operand)——运算符所作用的对象。例如,在 5 * 2 这个乘法运算中,有两个操作数:左侧操作数5,右侧操作数2。有时,人们也称它们为“参数”(arguments)而不是“操作数”。

  • 一元运算符(unary operator)——如果运算符只有一个操作数,则称为一元运算。例如,一元负号 - 会改变数字的符号:

    let x = 1;
    
    x = -x;
    alert( x ); // -1, unary negation was applied

同样的减号 - 也存在二元形式:

let x = 1, y = 3;
alert( y - x ); // 2, binary minus subtracts values

正式来说,在上述示例中,我们有两个不同的运算符共享相同的符号:负号运算符(一元运算符,用于取反)和 减法运算符(二元运算符,用于两个数相减)。

数字(Number)类型

在编程中,即使是人人熟知的最普遍的十进制数,也比你想象的要复杂的多。我们使用不同的术语来描述不同类型的十进制数,例如:

  • 整数 就是整数,例如 10, 400, 或者 -5.
  • 浮点数 (浮点) 有小数点或小数位,例如 12.5,和 56.7786543。
  • 双精度双精度是一种特定类型的浮点数,它们具有比标准浮点数更高的精度(这意味着它们精确到更大的小数位数)。

我们甚至有不同类型的数字系统!十进制是基数 10(意味着它在每列使用 0-9),但是我们也有这样的东西:

  • 二进制——计算机的最基础语言——0 和 1
  • 八进制——基数 8,每列使用 0-7
  • 十六进制——基数 16,每列使用 0-9,然后使用 a-f。在 CSS 中设置颜色时,可能会遇到这些数字。

在你开始担心你的大脑混乱之前,先停下来吧!一开始,我们将在本课程中坚持使用十进制数; 你很少会遇到需要开始考虑其他类型的情况,如果有的话。

第二个好消息是,与其他一些编程语言不同,JavaScript 只有一个数据类型用来表示数字(包括 integers 和 decimals),你猜对了,Number。这意味着,你在 JavaScript 中处理的任何类型的数字,都以完全相同的方式处理它们。

我们已经在javascript数据类型中解释了 Number(数字)数据类型

算术运算符

算术运算符是我们用来做和的基本运算符

运算符 名称 作用 示例
+ 加法 两个数相加。 6 + 9
- 减法 从左边减去右边的数。 20 - 15
* 乘法 两个数相乘。 3 * 7
/ 除法 用右边的数除左边的数 10 / 5
% 求余 (有时候也叫取模) 在你将左边的数分成同右边数字相同的若干整数部分后,返回剩下的余数 8 % 3 (返回 2,8 除以 3 的倍数,余下 2。)
** 取底数的指数次方,即指数所指定的底数相乘。它在 EcmaScript 2016 中首次引入。 5 ** 5 (返回 3125,相当于 5 * 5 * 5 * 5 * 5 。)

备注: 你以后有时候会看到参与算术计算的数字被称为 操作数 (operands)。

备注: 有时你可能会看到使用较旧的 Math.pow() 方法表达的指数,该方法的工作方式非常相似。例如,在 Math.pow(7, 3) 中,7 是基数,3 是指数,因此表达式的结果是 343Math.pow(7, 3) 相当于 7 ** 3

我们可能不需要教你如何做基础数学,但我们想测试你对所涉及的语法的理解。尝试将下面的示例输入到开发者工具 JavaScript 控制台中。

取余运算符 %

取余运算符 %,尽管看起来像百分比,但与百分比无关。

表达式 a % b 的结果是 ab 整除后的余数

例如:

alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
alert( 8 % 4 ); // 0, the remainder of 8 divided by 4

幂运算 **

运算符 a ** b 表示 ab 次方

在数学中,我们通常写作 aᵇ

例如:

alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16

就像在数学中一样,幂运算符也适用于非整数数值。

READ  为什么python大数据受欢迎?

例如,平方根 可以表示为 1/2 次幂

alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)

使用二元运算符 + 进行字符串连接

让我们看看 JavaScript 运算符的一些超出学校算术范围的特性。

通常,加号 + 用于数值相加

但如果二元 + 作用于字符串,它会合并(连接)它们:

let s = "my" + "string";
alert(s); // mystring

请注意,如果任一操作数是字符串,则另一个操作数也会被转换为字符串。

例如:

alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"

可以看到,无论第一个操作数还是第二个操作数是字符串,都会触发字符串连接

这里有一个更复杂的例子:

alert(2 + 2 + '1' ); // "41" and not "221"

在这里,运算符依次执行的。第一个 + 先对两个数字求和,结果是 4,然后下一个 + 将字符串 '1' 添加进去,所以相当于:

4 + '1' = '41'

alert('1' + 2 + 2); // "122" and not "14"

在这里,第一个操作数是一个字符串,编译器会将另外两个操作数也视为字符串处理。数字 2 会与字符串 '1' 连接,因此变成了 '1' + 2 = "12",然后 "12" + 2 = "122"

二元 + 是唯一一个以这种方式支持字符串的运算符。其他算术运算符仅适用于数字,并且始终将它们的操作数转换为数字。

下面是减法和除法的示例:

alert( 6 - '2' ); // 4, converts '2' to a number
alert( '6' / '2' ); // 3, converts both operands to numbers

数字转换,一元加号运算符(Unary +)

加号 + 有两种形式:我们上面使用的二元形式和一元形式。

一元加号,换句话说,+ 运算符作用于单一值时,对数字没有任何影响。但如果操作数不是数字,一元加号会将其转换为数字。

例如:

// No effect on numbers
let x = 1;
alert( +x ); // 1

let y = -2;
alert( +y ); // -2

// Converts non-numbers
alert( +true ); // 1
alert( +"" );   // 0

它实际上和 Number(...) 做的事情相同,只是更简短。

将字符串转换为数字的需求非常常见。例如,如果我们从 HTML 表单字段获取值,它们通常是字符串。那么,如果我们想将它们相加呢?

二元加号会将它们作为字符串相加:

let apples = "2";
let oranges = "3";

alert( apples + oranges ); // "23", the binary plus concatenates strings

如果我们想将它们当作数字处理,就需要先转换它们,再进行相加:

let apples = "2";
let oranges = "3";

// both values converted to numbers before the binary plus
alert( +apples + +oranges ); // 5

// the longer variant
// alert( Number(apples) + Number(oranges) ); // 5

从数学家的角度来看,多个加号可能显得有些奇怪。但从程序员的角度来看,这没什么特别的:一元加号优先应用,它们将字符串转换为数字,然后二元加号再将它们相加。

为什么一元加号在二元加号之前应用?正如我们将看到的那样,这是因为一元加号的优先级更高。

运算符优先级

运算符优先级

如果一个表达式中包含多个运算符,运算顺序由它们的**优先级(precedence)**决定,换句话说,也就是运算符的默认优先顺序。

我们在学校里都学过,表达式 1 + 2 * 2 中,乘法应在加法之前计算。这就是优先级的体现。我们说乘法的优先级高于加法。

括号会覆盖任何优先级,所以如果我们不满意默认的运算顺序,可以使用括号进行调整。例如:(1 + 2) * 2

JavaScript 中有很多运算符,每个运算符都有对应的优先级数字。数字越大,优先级越高,执行越早。如果优先级相同,则按从左到右的顺序执行。

READ  JavaScript while 循环语句

下面是优先级表的一个节选(你不需要记住它,但请注意:一元运算符的优先级高于对应的二元运算符):

算术运算符优先级
算术运算符优先级

如我们所见,“一元加号”的优先级是 14,高于“加法”(二元加号)的 11。

这就是为什么在表达式 +apples + +oranges 中,一元加号会先执行,然后才进行加法运算。

赋值(Assignment)运算符

需要注意,赋值符号 = 也是一个运算符。在优先级表中,它的优先级非常低,为 2

这就是为什么在我们进行赋值时,比如 x = 2 * 2 + 1,表达式中的计算会先执行,然后才执行赋值 =,将结果存储到变量 x 中。

let x = 2 * 2 + 1;

alert( x ); // 5

赋值 = 会返回一个值

赋值符号 = 是一个运算符。在 JavaScript 中,所有运算符都会返回一个值。这对 +- 来说显而易见,但对 = 也是如此。

表达式 x = value 会将值写入 x然后返回该值

下面是一个将赋值作为复杂表达式一部分的示例:

let a = 1;
let b = 2;

let c = 3 - (a = b + 1);

alert( a ); // 3
alert( c ); // 0

在上面的示例中,表达式 (a = b + 1) 的结果是赋给 a 的值(也就是 3)。这个值随后被用于后续的计算。

挺有趣的代码,不是吗?我们应该理解它是如何工作的,因为在一些 JavaScript 库中确实会看到这种写法。

不过,请不要自己写这种代码。这种“技巧”并不会让代码更清晰或者更易读。

链式赋值(Chaining assignments)

另一个有趣的特性是可以进行链式赋值

let a, b, c;

a = b = c = 2 + 2;

alert( a ); // 4
alert( b ); // 4
alert( c ); // 4

链式赋值从右向左进行求值的。首先,最右侧的表达式 2 + 2 被计算出来,然后这个值依次赋给左边的变量:cba。最终,所有变量拥有相同的值。

不过,为了代码的可读性,最好将这样的代码拆分成几行:

c = 2 + 2;
b = c;
a = c;

这样更易于阅读,尤其是在快速浏览代码时。

就地修改(Modify-in-place)

我们经常需要对一个变量应用某个运算符,并将新的结果存回这个变量本身

let n = 2;
n = n + 5;
n = n * 2;

这种写法可以通过运算符 +=*= 等进行简化:

let n = 2;
n += 5; // now n = 7 (same as n = n + 5)
n *= 2; // now n = 14 (same as n = n * 2)

alert( n ); // 14

几乎所有算术和位运算符都有对应的简写“修改并赋值”运算符,如:/=-= 等。

这类运算符优先级与普通赋值运算符相同,因此它们在大多数其他运算之后执行:

let n = 2;

n *= 3 + 5; // right part evaluated first, same as n *= 8

alert( n ); // 16

但是还有一些更复杂的类型,它们提供了有用的快捷方式,可以使你的代码更加清洁和高效。最常见的如下:

运算符 名称 作用 示例 等价于
+= 加法赋值 右边的数值加上左边的变量,然后再返回新的变量。 x = 3; x += 4; x = 3; x = x + 4;
-= 减法赋值 左边的变量减去右边的数值,然后再返回新的变量。 x = 6; x -= 3; x = 6; x = x - 3;
*= 乘法赋值 左边的变量乘以右边的数值,然后再返回新的变量。 x = 2; x *= 3; x = 2; x = x * 3;
/= 除法赋值 左边的变量除以右边的数值,然后再返回新的变量。 x = 10; x /= 5; x = 10; x = x / 5;

 

自增和自减运算符

有时候,你需要反复把一个变量加 1 或减 1。这可以方便地使用增量(++)和递减( --运算符来完成。我们在JavaScript 初体验文章的“猜数字”游戏中使用了++,当我们添加 1 到我们的 guessCount 变量来跟踪用户在每次转动之后剩下的猜测时。

语法:

guessCount++;

JavaScript按位运算符

按位运算符操作数当作 32 位整数 来处理,并在它们的二进制表示层面上进行操作。

这些运算符不仅限于 JavaScript,大多数编程语言都支持它们。

JavaScript按位运算符
JavaScript按位运算符

Javascript 逗号运算符(Comma)

逗号运算符 , 是最少见、最不常见的运算符之一。有时候它被用来写更简短的代码,所以我们需要了解它,以便看懂别人的代码。

READ  javascript 类型转换(Type Conversions)
Javascript 逗号运算符(Comma)
Javascript 逗号运算符(Comma)

运算符优先级

括号中的表达式在表达式的其余部分之前计算,函数在结果用于表达式的其余部分之前执行:

优先级 运算符 描述 例子
18 ( ) 表达式分组 (100 + 50) * 3
17 . 属于成员 person.name
17 [] 属于成员 person[“name”]
17 ?. 可选链 ES2020 x ?. y
17 () 函数调用 myFunction()
17 new 带参的新建 new Date(“June 5,2022”)
16 new 不带参的新建 new Date()

增量运算符

后缀递增在前缀递增之前执行。

15 ++ 后缀递增 i++
15 后缀递减 i–
14 ++ 前缀递增 ++i
14 前缀递减 –i

NOT 运算符

14 ! 逻辑非 !(x==y)
14 ~ 按位非 ~x

一元运算符

14 + 一元加 +x
14 一元减 -x
14 typeof 数据类型 typeof x
14 void 评估空 void(0)
14 delete 属性删除 delete myCar.color

算术运算符

指数运算在乘法之前执行。

乘法和除法在加法和减法之前执行。

13 ** 指数运算 ES2016 10 ** 2
12 * 10 * 5
12 / 10 / 5
12 % 除法余数 10 % 5
11 + 10 + 5
11 10 – 5
11 + 串联 “Bill” + “Gates”

移位运算符

10 << 左移 x << 2
10 >> 右移(带符号) x >> 2
10 >>> 右移(无符号) x >>> 2

关系运算符

9 in 对象中的属性 “PI” in Math
9 instanceof 对象的实例 x instanceof Array

比较运算符

9 < 小于 x < y
9 <= 小于或等于 x <= y
9 > 大于 x > y
9 >= 大于或等于 x >= Array
8 == 等于 x == y
8 === 严格相等 x === y
8 != 不相等 x != y
8 !== 严格不相等 x !== y

位运算符

7 & 按位与 x & y
6 ^ 按位异或 x ^ y
5 | 按位或 x | y

逻辑运算符

4 && 逻辑与 x && y
3 || 逻辑或 x || y
3 ?? 空值合并 ES2020 x ?? y

条件(三元)运算符

2 ? : 条件 ? “yes” : “no”

赋值运算符

赋值在其他操作之后执行。

2 = 简单赋值 x = y
2 : 冒号赋值 x: 5
2 += 加法赋值 x += y
2 -= 减法赋值 x -= y
2 *= 乘法赋值 x *= y
2 **= 指数赋值 x **= y
2 /= 除法赋值 x /= y
2 %= 取余赋值 x %= y
2 <<= 左移赋值 x <<= y
2 >>= 右移赋值 x >>= y
2 >>>= 无符号右移 x >>>= y
2 &= 位与赋值 x &= y
2 |= 位或赋值 x |= y
2 ^= 位异或赋值 x ^= y
2 &&= 逻辑与赋值 x &= y
2 ||= 逻辑或赋值 x ||= y
2 => 箭头 x => y
2 yield 暂停 / 恢复 yield x
2 yield* 委托运算符 yield* x
2 展开运算符 … x
1 , 逗号 x , y

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!
Posted in JavaScript 基础

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!