06-运算符
晴空闲云 533 1

本节目标

  1. 掌握js语言中各类型运算符的使用。
  2. 掌握短路与和短路或的原理。
  3. 掌握二进制运算符的计算原理。
  4. 掌握计算机中各进制的转换方式。

内容摘要

本篇对js中的运算符进行了详细的梳理,共梳理了8种运算符,允许我骄傲一下,自夸全网前三了。 每类运算符都列举了相关的例子进行了说明,顺便带出了一些js奇怪的知识。

阅读时间大于30~40分钟。

运算符介绍

计算机是用来计算的,那么作为一款编程语言,自然也有自己的运算符的。

js中运算符分为如下几类:

1. 算数运算符
2. 赋值运算符
3. 比较运算符
4. 布尔运算符
5. 三元运算符
6. 位运算符
7. 字符串连接符
8. 类型运算符

下面我们对各运算符逐一讲解。

算数运算符

算数运算符包含:

加法运算符(Addition):x + y
减法运算符(Subtraction): x - y
乘法运算符(Multiplication): x * y
除法运算符(Division):x / y
余数运算符(Remainder):x % y
求负运算符(Negate):-x
自增运算符(Increment):++x 或者 x++
自减运算符(Decrement):--x 或者 x--
数值运算符(Convert to number): +x
幂运算符(Power):x ** y

根据难易度,我们分成4个部分讲解:加减乘除模求负、自增自减、转成数值、幂运算符。

加减乘除模求负

其中加减乘除模求负比较简单,我们来个通用的示例。

示例1,声明变量x、y,进行加减乘除运算。

let x = 5;
let y = 2;
console.log(x + y); // ?
console.log(x - y); // ?
console.log(x * y); // ?
console.log(x / y); // ?
console.log(x % y); // ?
console.log(-x); // ?

自增自减

自增 ++x 和 x++,等同于:x = x + 1,++在前表示先加后用,在后表示先用后加。

自减 --x 和 x--,等同于:x = x - 1,--在前表示先减后用,在后表示先用后减。

示例1,阅读如下代码,分析输出。

let x = 5;
console.log(x++); // ?
console.log(++x); // ?
console.log(--x); // ?
console.log(x--); // ?
console.log(x); // ?

这边主要是考察大家对计算顺序的理解。

数值运算符

这个符号有点意思,我们先看个示例。

示例1,让用户输入两个数字,然后相加:

let x = window.prompt("请输入第一个数字:");
let y = window.prompt("请输入第二个数字:");
console.log(x + y); // ?

运行输入x=1、y=2,两个数字相加结果等于12,为嘛不是3?又被坑到了吧!

这边的原因很简单,因为输入的x和y都是字符串,+号在这边是后面要提到的字符串连接符号,所以结果就是12了。

知道原因后,改进方法就很简单了,在输入方法前面来个+号就可以了。

let x = +window.prompt("请输入第一个数字:");
let y = +window.prompt("请输入第二个数字:");
console.log(x + y);

幂运算符

js还有一个幂运算符,用来求数字的幂。

示例1,声明两个数字,求幂:

let x = 3;
let y = 4;
console.log(x**y); // ?

该方法在旧的浏览器上,如果IE浏览器上并不支持,一般用Math.pow代替。

console.log(Math.pow(x, y)); // ?

赋值运算符

赋值运算符包含以下运算符:

x = y  =表示赋值运算符
x += y  等同于 x = x + y
x -= y  等同于 x = x - y
x *= y  等同于 x = x * y
x /= y  等同于 x = x / y
x %= y  等同于 x = x % y
x >>= y  等同于 x = x >> y
x <<= y  等同于 x = x << y
x >>>= y  等同于 x = x >>> y
x &= y  等同于 x = x & y
x |= y  等同于 x = x | y
x ^= y  等同于 x = x ^ y

其中,=念等号没有问题,但是不同于数学上的概念,计算机中=号表示赋值的意思,即=右边的表达式赋值给左边。

示例1,阅读如下代码,分析输出:

let x = 5;
let y = 2;
console.log(x+=y); // ?
console.log(x*=y); // ?
console.log(x-=y); // ?
console.log(x/=y); // ?
console.log(x%=y); // ?

比较运算符

比较运算符包含以下运算符:

== 相等
=== 严格相等,类型和值要相等
!= 不相等
!== 严格不相等
< 小于
<= 小于或等于
> 大于
>= 大于或等于

示例1,来一些简单的例子,分析输出:

let x = 5; y = 2;
console.log(x == y); // ?
console.log(x != y); // ?
console.log(x < y); // ?
console.log(x > y); // ?

示例2,来一些比较难的,分析输出:

console.log(0 == ''); // ?
console.log([] == 0); // ?
console.log([] == ''); // ?
console.log([] == undefined); // ?
console.log(0 == null); // ?

布尔运算符

布尔运算符包含以下运算符:

! 取反运算符
&& 且运算符
|| 或运算符

!取反运算符

! 取反运算符,用于将布尔值变为相反值,即 true 变成 false , false 变成 true。

console.log(!true); // false
console.log(!false); // true

对于非布尔值的数据,取反运算符会自动将其转成布尔值,下面6个值取反后为true,其他值取反都为false。

undefined
null
false
0(包括+0和-0)
NaN
空字符串('')

看个简单的示例:

console.log(!null); // true
console.log(![]); // false

这意味着,取反运算符有转换数据类型的作用,如果对一个数字连续取反两次,就可以转化成布尔值:

console.log(!!null); // false
console.log(!![]); // true

类似Boolean函数的作用。

&&且运算符

&&且运算符用来对两个表达式进行真假运算,规则如下:

1. 两边条件都为true时,结果才为true。
2. 如果有一个为false,结果就为false。
3. 当第一个条件为false时,就不再判断后面的条件,俗称短路与。

参考如下例子:

console.log(true && true); // true
console.log(false && true); // false

思考:

阅读如下代码,分析最终x的值等于多少?

let x;
console.log(false && (x = 1)); // ?
console.log(x); // ?

解答:

最终x的值等于undefined,因为在上面的&&运算中,第一个条件为false,就不会执行后面的表达式了,这个就是上面第3个规则的意思了。

||或运算符

||或运算符类似&&运算符,规则如下:

1. 两边条件其中一个为true时,结果就为true。
2. 如果两个条件都为false,结果就为false。
3. 当第一个条件为true时,就不再判断后面的条件,俗称短路或。

参考如下例子:

console.log(true || true); // true
console.log(false || true); // true
console.log(false || false); // false

三元运算符

网上有的说法叫条件运算符,我觉得这个都ok,因为就是有一个条件判断,然后确定后面取值。

三元运算符的语法格式如下:

条件 ? 条件为真走这里 : 条件为假走这里

例如:

let a = 10, b = 7;
let x = (a > b) ? a : b; // 10

位运算符

位运算符包含以下运算符:

或运算(or):符号为|,表示两个二进制位中有一个为1,则结果为1,否则为0。
与运算(and):符号为&,表示两个二进制位都为1,则结果为1,否则为0。
异或运算(xor):符号为ˆ,表示两个二进制位中有且仅有一个为1时,结果为1,否则为0。
否运算(not):符号为~,表示将一个二进制位变成相反值。
左移运算(left shift):符号为<<
右移运算(right shift):符号为>>

这边的难点主要是在于二进制,计算机存储的都是二进制的数据。比如:4在计算机中就是表示为100。

示例1,对5和2进行或、与、异或位运算:

console.log(5 | 2); // 7
console.log(5 & 2); // 0
console.log(5 ^ 2); // 7

这边5的二进制是101,2的二进制是10,进行或运算:

    101
    010
-----------
    111  --------> 7

进行与运算:

    101
    010
-----------
    000  --------> 0

进行异或运算:

    101
    010
-----------
    111  --------> 7

示例2,对5进行否运算、左移运算和右移运算。

console.log(~5);
console.log(5 << 2);
console.log(5 >> 2);

这边5的二进制是101,进行否运算:

1. 补满32位:0000 0000 0000 0000 0000 0000 0000 0101
2. 按位取反:1111 1111 1111 1111 1111 1111 1111 1010
3. 首位符号位位1表示负数,计算表示的数需要先反码,再+1
4. 按位取反:0000 0000 0000 0000 0000 0000 0000 0101
5. 加上1:0000 0000 0000 0000 0000 0000 0000 0110
6. 最终结果就是:-6

进行左移两位运算:

1. 5的二进制是:101
2. 左移两位: 10100
3. 转成十进制:20

进行右移两位运算:

1. 5的二进制是:101
2. 右移两位:1,后面的01倍舍弃了。
3. 转成十进制:1

字符串连接符

js中用加号+进行连接字符串。

console.log("Hello" + " " + "world" + "!"); // Hello world!

思考:

阅读如下代码,分析输出:

let num1 = 1, num2 = 2;
console.log(num1 + num2); // ?

解答:

因为这个符号和数学加号是一致的,所以说如果要连接两个数字,直接写成:num1+num2,就会有问题了。

我们可以把num1和num2转换成字符串再拼接,或者在前面拼接一个空字符串就可以了。

console.log("" + num1 + num2); 

类型运算符

位运算符包含以下运算符:

typeof:用于查找JavaScript变量的数据类型,返回变量的类型。
instanceof:用来判断某个构造函数的prototype属性是否存在在另一个要检测对象的原型链上,返回一个Boolean值,指出对象是否是特定类的一个实例。

typeof

typeof前面有用过了,就是返回变量的类型:

console.log(typeof 1); // ?
console.log(typeof '666'); // ?
console.log(typeof true); // ?
console.log(typeof null); // ?
console.log(typeof undefined); // ?
console.log(typeof NaN); // ?
console.log(typeof []); // ?
console.log(typeof {}); // ?

前面讲解数据类型有用过,不再赘述。值得一提的是这边NaN的类型是number,但是NaN的意思就是not a number,又惊呆了吧!

除此之外:NaN === NaN 是false,我也不知道要说什么了。我只能解释,因为两个都不是数字,那能代表两个相等吗?

instanceof

instanceof用来判断某个构造函数的prototype属性是否存在在另一个要检测对象的原型链上,返回一个Boolean值,指出对象是否是特定类的一个实例。

我们看些例子:

console.log([] instanceof String); // false
console.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log({} instanceof Object); // true

这边[]实际上是一个数组对象。

本节总结

  1. 本节对js中的运算符做了详细的梳理,共梳理出8种运算符。
  2. 自增自减顺序问题,符号在前的先算后用,符号在后的先用后算。
  3. 位运算符需要了解二进制相关的转换。

练习题

  1. parseInt和parseFloat函数有什么作用?请举例说明。和数值运算符+的异同点。
  2. 说明parseInt、parseFloat和数值运算符的异同点。
  3. 请问:"cat" > "john" 是true还是false,为什么呢?
  4. Boolean函数有什么作用?请举例说明。
  5. 短路与(&&)和短路或(||)是怎么一回事?请举例说明。
  6. 让用户输入一个数字,如果大于100,那么打印100,否则打印用户输入的数字。
  7. ~10、10 << 1、10 >> 2 分别等于多少?写出计算思路。
  8. 二进制、八进制、十进制和十六进制之间如何互相转换?
  9. 除了用加号+连接字符串,其他还有什么方式?
  10. 为什么typeof array 返回的是object,而不是array?
  11. "888" instanceof String 返回的结果是true还是false?为什么?
评论区

索引目录