盒子
文章目录
  1. 11. 运算符
    1. 11.1. 运算符两个重要的规则
      1. 11.1.1. 运算符两个重要的规则
      2. 11.1.2. 大多数运算符只对原始类型起作用
    2. 11.2. 加号plus
    3. 11.3. 赋值运算符
      1. 11.3.1. 基本的赋值运算符
      2. 11.3.2. 复合赋值运算符
      3. 11.3.3. 所有可复合的运算符
    4. 11.4. 相等运算: == VS ===
      1. 11.4.1. 宽松相等(== and !=)
      2. 11.4.2. 严格相等 (=== and !==)
      3. 11.4.3. 推荐:总是使用严格模式
        1. 11.4.3.1. 使用 ==:比较一个数字和字符串
        2. 11.4.3.2 ==: 比较undefined 和 null
    5. 11.5. 排序运算
    6. 11.6. 其他的运算符

不耐烦的 JSer

11. 运算符

11.1. 运算符两个重要的规则

1. 强制让运算数变为合适的类型
2. 大多数运算符只对原始类型有效

11.1.1. 运算符两个重要的规则

一个运算符操作的的数据类型不匹配, JS基本不会抛出异常。相反,它会自动进行强制类型转换。以便于这样看起来是正常运算的。让我们来看下面两个例子。

首先,一个乘法运算只可以让两个数字正常工作,因此,在相乘之前,他会将字符转换成数字。

'7' * '3'
21

其次, 用于访问对象属性的操作符[]只能处理字符串或者symbol。其他的值会被强制转换成字符串。其他的字都会转换成字符串。

11.1.2. 大多数运算符只对原始类型起作用

对于JS操作符需要要记住的规则是:大多数运算符只对原始类型起作用

如果运算数是对象,则经常会被强制转换成基本类型。

例如:

> [1,2,3] + [4,5,6]
'1,2,34,5,6'

为什么?因为 +操作符会首先将运算数转换成原始类型

> String([1,2,3])
'1,2,3'
> String([4,5,6])
'4,5,6'

11.2. 加号plus

在JS中,加号按以下方式工作:首先它会将运算数转换成基本类型,然后它会切到两种模式之一:

  • 字符串模式:如果一个被转换成的基本类型有一个是字符串,那么另外一个也会被转换成字符串,最后字符串会进行连接。
  • 数字模式:除此之外,两边的运算数会被转换成数字,然后进行相加。

字符串模式可以让你使用+去连接字符串。

> 'There are ' + 3 + ' items'
'There are 3 items'

数字模式意味着如果。如果运算数两边都不是数字(或者一个对象变成了字符串)那么都会被变成数字:

> 4 + true
5

11.3. 赋值运算符

11.3.1. 基本的赋值运算符

  • x = value

    给一个声明的变量赋值

  • const x = value
    同时进行声明和复制

  • obj.propKey = value
    给一个属性赋值

  • arr[index] = value
    给数组的某个元素赋值

11.3.2. 复合赋值运算符

给出的运算符工作时,以下两种方式是相同的

myvar op= value
myvar = myvar op value

举例来说,复合+,然后我们可以得到运算符+=它会像下面的工作:

let str = '';
str += '<b>';
str += 'Hello!';
str += '</b>';

assert.equal(str, '<b>Hello!</b>');

11.3.3. 所有可复合的运算符

数学运算:

+= -= *= /= %= **=

+= 同样对字符串连接有效

按位运算符:

11.4. 相等运算: == VS ===

JS 有两种等号运算符:宽松相等(==)和严格相等(===),推荐总是使用后者判断是否相等。

11.4.1. 宽松相等(== and !=)

宽松相等是JS的特性之一。它经常会强制转换操作数,有些强制转换是起作用的:

> '123' == 123
true
> false == 0
true

大多数情况下意义不大:

> '' == 0
true

对象被强制转换成基本类型。当且只当另外一个运算数是基本类型。

> [1, 2, 3] == '1,2,3'
true
> ['1', '2', '3'] == '1,2,3'
true

如果两个操作数都是对象,当他们是同一个对象时才相等:

> [1, 2, 3] == ['1', '2', '3']
false
> [1, 2, 3] == [1, 2, 3]
false

> const arr = [1, 2, 3];
> arr == arr
true

最后,== 允许了undefined和null相等

11.4.2. 严格相等 (=== and !==)

严格相等从不会类型转换。两个相等的值一定会有相同的类型。让我们复习一遍之前的==运算符,然后看===是怎样工作的

如果两个运算数都是对象,当他们是同一个对象时才相等:

> [1, 2, 3] === '1,2,3'
false
> ['1', '2', '3'] === '1,2,3'
false

> [1, 2, 3] === ['1', '2', '3']
false
> [1, 2, 3] === [1, 2, 3]
false

> const arr = [1, 2, 3];
> arr === arr
true

=== 运算符不允许undefined和null相等

> undefined === null
false

11.4.3. 推荐:总是使用严格模式

推荐总是使用===。他会让你的代码可读性更高。把你从不得不思考怪异的==中解脱出来。
让我们看一下两个case:使用==的和我推荐的替代方案.

11.4.3.1. 使用 ==:比较一个数字和字符串

== 让你去判断一个值x是一个数字,或者作为字符串的数字,通过单个的比较:

if (x == 123) {
// x is either 123 or '123'
}

我更喜欢以下两种替代方案:

if (x === 123 || x === '123') ···
if (Number(x) === 123) ···

你也可以在第一次遇见他的时候将它进行类型转换:

11.4.3.2 ==: 比较undefined 和 null

使用==的另外一个case是比较undefined 或 null

if (x == null) {
// x is either null or undefined
}

这段代码的问题在于,你无法保证是其他人也会用这种方式判断,或者有人有用meant === null的方式。

我更喜欢一下两者任意替代方式:

if (x === undefined || x === null) ···
if (x) ···

第二种替代方式是相对更常见,但是塔毁坏了一些在JS中的一些模式。
the chapter on booleans会解释到, 我们会看到现象与本质。

11.5. 排序运算

Table 2: JavaScript’s ordering operators.

Operator name
< 小于
<= 小于等于
> 大于
>= 大于等于

JS的比较运算符规则(tbl. 2) 对字符串和数字同样生效。

警告:这些运算符在比较人类语言中的文本(大写、重音等)时效果不佳。有关详细信息,请参阅[字符串章节](http://exploringjs.com/unatint js/ch_operators.html/ch_strings.html比较字符串)。

11.6. 其他的运算符

  • 对于布尔,字符串,数组或对象在本书其他章节也有提到。