本节目标
- 掌握js语言中各类型运算符的使用。
- 掌握短路与和短路或的原理。
- 掌握二进制运算符的计算原理。
- 掌握计算机中各进制的转换方式。
内容摘要
本篇对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
这边[]实际上是一个数组对象。
本节总结
- 本节对js中的运算符做了详细的梳理,共梳理出8种运算符。
- 自增自减顺序问题,符号在前的先算后用,符号在后的先用后算。
- 位运算符需要了解二进制相关的转换。
练习题
- parseInt和parseFloat函数有什么作用?请举例说明。和数值运算符+的异同点。
- 说明parseInt、parseFloat和数值运算符的异同点。
- 请问:"cat" > "john" 是true还是false,为什么呢?
- Boolean函数有什么作用?请举例说明。
- 短路与(&&)和短路或(||)是怎么一回事?请举例说明。
- 让用户输入一个数字,如果大于100,那么打印100,否则打印用户输入的数字。
- ~10、10 << 1、10 >> 2 分别等于多少?写出计算思路。
- 二进制、八进制、十进制和十六进制之间如何互相转换?
- 除了用加号+连接字符串,其他还有什么方式?
- 为什么typeof array 返回的是object,而不是array?
- "888" instanceof String 返回的结果是true还是false?为什么?