编程向导-JavaScript-基础语法-算术/赋值/逗号/运算符

算术运算符

算术运算符使用数值(字面量或者变量)作为操作数进行运算并返回一个数值。

标准的算术运算符就是加减乘除 +-*/

当操作数是浮点数时,这些运算符表现得跟它们在大多数编程语言中一样(特殊要注意的是,除零会产生 Infinity )。

运算符描述示例
+加法1 + 1 = 2
-减法2 - 1 = 1
*乘法3 * 3 = 9
/除法10 / 5 = 2
%求余,返回相除后余值12 % 5 = 2
++自增(更新运算符),分为前自增和后自增具体参考 更新运算符
--自减(更新运算符),分为前自减和后自减具体参考 更新运算符
-一元负值符,返回操作数的负值-foo
+一元正值符,若操作数在操作前非数字类型,将试图将其转换成数字类型+foo
**指数运算符,计算 base(底数) 的 exponent(指数)次方2 ** 3 = 8

实践示例

console.log(-9 % 2);
// -1

console.log(1 + -+(+(+-+1)));
// 2

实现指数运算符

function calculateExponent(base, exponent) {
  if (exponent === 1) {
    return base;
  } else {
    return base * calculateExponent(base, exponent - 1);
  }
}

赋值运算符

一个 赋值运算符(assignment operator)将它右边操作数的值赋给它左边的操作数。

下列为 ECMAScript 标准规范的 Assignment Operator:

* = /= %= += -= <<= >>= >>>= &= ^= |= **=

运算名称简写的操作符分解含义符号
赋值x = yx = y=
加法赋值x += yx = x + y+=
减法赋值x -= yx = x - y-=
乘法赋值x *= yx = x * y*=
除法赋值x /= yx = x / y/=
求余赋值x %= yx = x % y%=
求幂赋值x ** yx = x ** y**
左移位赋值x <<= yx = x << y<<=
右移位赋值x >>= yx = x >> y>>=
无符号右移位赋值x >>>= yx = x >>> y>>>=
按位与赋值x & yx = x & y&
按位异赋值x ^= yx = x ^ y^=
按位或赋值x |= yx = x | y| y

逗号运算符

逗号运算符二元运算符,它的操作数可以是任意类型。

它首先计算左操作数,然后计算右操作数,最后返回右操作数的值,用逗号运算符可以在一条语句中执行多个运算。

(x = 0), (y = 1), (z = 2);
// 计算结果是 2,它和下面的代码基本等价
x = 0;
y = 1;
z = 2;

用法

用于声明多个变量

var a = 1,
  b = 2,
  c = 3;

let x, y, z;

逗号运算符最常用的场景是在 for 循环中,这个 for 循环通常具有多个循环变量:

// for 循环中的第一个逗号是 var 语句的一部分
// 第二个逗号是逗号运算符
// 它将两个表达式(i++和j--)放在一条语句中
for (var i = 0, j = 10; i < j; i++, j--) {
  console.log(i + j);
}

用于赋值

逗号运算符还可以用于赋值,在用于赋值时,逗号运算符总是返回表达式中的最后一项。

var foo = (1, 2, 3, 4, 5);
// 去掉括号会报错

console.log(foo);
// 5


# 比较运算符

比较运算符比较它的操作数并返回一个基于表达式是否为 `true` 的逻辑值。

比较运算符分为**关系运算符(Relational Operators)****等值运算符(Equality Operators)**- 操作数可以是数字,字符串,逻辑,对象值。
- 字符串比较是基于标准的字典顺序,使用 Unicode 值。
- 在多数情况下,如果两个操作数不是相同的类型, JavaScript 会尝试转换它们为恰当的类型来比较。这种行为通常发生在数字作为操作数的比较。
- 类型转换的例外是使用 `===``!==` 操作符,它们会执行严格的相等和不相等比较。这些运算符不会在检查相等之前转换操作数的类型。下面的表格描述了该示例代码中的各比较运算符。

## 关系运算符

| 运算符        | 描述                                          | 返回 `true` 的示例 |
| ------------- | --------------------------------------------- | ------------------ |
| 大于 `>`      | 左边的操作数大于右边的操作数返回 `true`       | `b > a`            |
| 大于等于 `>=` | 左边的操作数大于或等于右边的操作数返回 `true` | `b >= a` `a >= 1`  |
| 小于 `<`      | 左边的操作数小于右边的操作数返回 `true`       | `a < b` `1 < 2`    |
| 小于等于 `<=` | 左边的操作数小于或等于右边的操作数返回 `true` | `a <= b` `b <= 5`  |

## 等值运算符

| 运算符       | 描述                                    | 返回 `true` 的示例             |
| ------------ | --------------------------------------- | ------------------------------ |
| 等于 `==`    | 如果两边操作数相等时返回 `true`         | `a == 1` `'1' == 2` `1 == '1'` |
| 不等于 `!=`  | 如果两边操作数不相等时返回 `true`       | `a != 2` `b != '1'`            |
| 全等 `===`   | 两边操作数相等且类型相同时返回 `true`   | `a === 1`                      |
| 不全等 `!==` | 两边操作数不相等或类型不同时返回 `true` | `a !== '1'` `1 !== '1'`        |

### 抽象相等比较算法

> 1.Type(x)Type(y) 相同,则
>    1.Type(x) 为 Undefined,返回 `true`
>    2.Type(x) 为 Null,返回 `true`
>    3.Type(x) 为 Number,则
>       1. 若 x 为 NaN,返回 `false`
>       2. 若 y 为 NaN,返回 `false`
>       3. 若 x 与 y 为相等数值,返回 `true`
>       4. 若 x 为 +0 且 y 为 -0,返回 `true`
>       5. 若 x 为 -0 且 y 为 +0,返回 `true`
>       6. 返回 `false`
>    4.Type(x) 为 String
>       1. 当 x 和 y 为完全相同的字符序列(长度相等且相同字符在相同位置)时返回 `true`
>       2. 否则,返回 `false`
>    5.Type(x) 为 Boolean
>       1. 当 x 和 y 为同为 `true` 或者同为 `false` 时返回 `true`
>       2. 否则,返回 `false`
>    6. 当 x 和 y 为引用用一对象时返回 `true`。否则,返回 `false`> 2. 若 x 为 null 且 y 为 undefined,返回 `true`
> 3. 若 x 为 undefined 且 y 为 null,返回 `true`
> 4.Type(x) 为 Number 且 Type(y) 为 String,返回比较 `x == ToNumber(y)` 的结果
> 5.Type(x) 为 String 且 Type(y) 为 Number,返回比较 `ToNumber(x) == y` 的结果
> 6.Type(x) 为 Boolean,返回比较 `ToNumber(x) == y` 的结果
> 7.Type(y) 为 Boolean,返回比较 `x == ToNumber(y)` 的结果
> 8.Type(x) 为 String 或 Number,且 Type(y) 为 Object,返回比较 `x == ToPrimitive(y)` 的结果
> 9.Type(x) 为 Object 且 Type(y) 为 String 或 Number,返回比较 `ToPrimitive(x) == y` 的结果
> 10. 返回 `false`

按以上相等之定义:

- 字符串比较可以按这种方式强制执行:`'' + a == '' + b`
- 数值比较可以按这种方式强制执行:`+a == +b`
- 布尔值比较可以按这种方式强制执行:`!a == !b`

等值比较操作保证以下不变:

- `A !== B` 等价于 `!(A == B)`
- `A == B` 等价于 `B == A`,除了 AB 的执行顺序。

相等运算符不总是传递的。例如,两个不同的 String 对象,都表示相同的字符串值;`==` 运算符认为每个 `String` 对象都与字符串值相等,但是两个字符串对象互不相等。

- `new String('a') == 'a'``'a' == new String('a')` 皆为 `true`
- `new String('a') == new String('a')``false`

字符串比较使用的方式是简单地检测字符编码单元序列是否相同。不会做更复杂的、基于语义的字符或者字符串相等的定义以及 Unicode 规范中定义的 Collating Order。所以 Unicode 标准中认为相等的 String 值可能被检测为不等。实际上这一算法认为两个字符串已经是经过规范化的形式。

### 引用数据类型间比较

```js
const a = function() {};
const b = function() {};

console.log(a === b);
// false

console.log([] === []);
// false

console.log({} === {});
// false

当我们访问引用数据类型(对象、数组、函数等等)的值时,首先从栈中获得该对象的 地址指针,然后再从 堆内存 中取得所需的数据。

变量 a 实际保存的是指向堆内存中对象的一个指针,而变量 b 保存的是指向堆内存中的另一个对象的指针,虽然这两个对象的值时一样的,但它们是独立的两个对象,占了两份内存空间,所以它们互不相等。

而当将一个为引用数据类型的值的变量赋值给另一个变量时,即拷贝了前者的内存空间的地址指针,因此它们都指向堆内存中同一个对象。

let x = {}

let y = x

console.log(x === y
// true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wtrees_松阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值