面试中的JS运算符
算数运算符
+-* /
- 余数%
//JS的错误
-1%7
//-1 而不是 6
- 指数 x**3
- 自增自减
x++ //这个表达式的值为x,最后返回x+1
++x //这个表达式的值为x+1,最后返回x+1
x-- //这个表达式的值为x,最后返回x-1
--x //这个表达式的值为x-1,最后返回x-1
尽量少用自增自减
- 求值运算符
// 可以将任何值转为数值(与Number函数的作用相同)
+(-1)// -1
+true // 1
+[] // 0
+{} // NaN
- 负数运算符
// 同样具有将一个值转为数值的功能,只不过得到的值正负相反
-(-1) // 1
-true // -1
-[] // -0
-{} // NaN
- JS的一个糟粕
1 + '2' //"12"
2 - '1' // 1
// +号运算符默认把所有运算子变成字符串然后运算
// -号运算符默认把所有运算子变成数值然后运算
比较运算符
- JS三位一体
意思是:
//0模糊相等于这些
0 == [] //true
0 == '0' //true
0 == '\t' //true
//但是,右边三个却不模糊相等!
结论: 永远不要使用==,用===代替。
==的问题在于,它总是自作聪明(自动类型转换)
x==y
真值表
令人难以理解
[] == false // 但不是falsy
[] == false // 但{}却不是
[[]] == false
x===y
真值表
没有任何费解
基本类型看值是否相等,对象看地址是否相等:
0 === [] // false 类型不相等
0 === 1 // false值相等
[] !== [] // true
{} !== {} // true
唯一特例:
NaN !== NaN
,强行记忆一下
布尔运算符
- 或且非
|| && !
- 短路逻辑
console&&console.log&&console.log(‘hi’) // 以防console不存在而报错
a = a || 100 // a的保底值
新版语法: 可选链 - JavaScript | MDN
二进制运算符
- 或、与、否 :
| & ~
- 异或
^ // 两个位相同,则结果为0,否则为1
(0b1111 ^ 0b1010).toString(2) // 101 实际上是0101
- 左移右移
<<
和>>
0b0010 >> 1 // 1 实际上是0001
0b0010 << 1 // 0100
0b0011 >> 1 // 0001
- 头部补零的右移运算符
>>>
(正数的情况下,和普通右移差不多) - 位运算符的一些妙用: 使用&运算符判断一个数的奇偶:
// 偶数 & 1 = 0
// 奇数 & 1 = 1
console.log(2 & 1) // 0
console.log(3 & 1) // 1
使用~, >>, <<, >>>, |
来取整:
console.log(~~ 6.83) // 6
console.log(6.83 >> 0) // 6
console.log(6.83 << 0) // 6
console.log(6.83 | 0) // 6
// >>>不可对负数取整
console.log(6.83 >>> 0) // 6
使用^
来交换a和b的值:
//用JS新语法交换a和b
var a = 5 //0101
var b = 8 //1000
[a, b] = [b, a]
//面试: 不准用,用位运算做一下
a ^= b // a: 1101, b: 1000
b ^= a // a: 1101, b: 0101
a ^= b // a: 1000, b: 0101
console.log(a) // 8
console.log(b) // 5
参考资料: 位运算符在JS中的妙用
其他运算符
点运算符
- 语法: 对象.属性名 = 属性名
- 作用: 读取或者设置对象的属性值
Q: 不是对象,为什么也可以有属性? 例如
'a-b-c’split(“-‘)
A: JS有特殊逻辑,点前面不是对象,就把它封装成对象,这些封装对象会指向对应的原型,原型会有属性。
number会变成Number对象, string会变成String对象,bool会变成Boolean对象
用完封装对象,就立即把这个封装对象从Heap堆里删掉。
这三种对象从来不用,只用简单类型
void运算符
- 语法: void表达式或语句
- 作用: 求表达式的值,或执行语句
void的值总返回undefined
- 需求:
<!-- return假值可以阻止默认动作(例如不跳转)-->
<a href="http://example.com" onclick="f(); return false;">点击</a>
<!-- 改用void可以炫技 -->
<a href="javascript: void(f())">文字</a>
<!-- 其实没用,直接这样 -->
<a href="javascript:;">google</a>
逗号运算符
- 语法: 表达式1,表达式2,…,表达式3
- 作用:将表达式n的值作为整体的值
let a = (1,2,3,4,5)
a // 5
- 使用
let f = (x,y) => (console.log('Hi'),x+y)
//等价于
let f = (x,y) => {console.log('Hi') return x+y}
运算符优先级
- 具体规则想知道吗?
- 你: 想。
- 不,你不想!看看运算符优先级 - JavaScript | MDN,你就知道为什么了:(
圆括号优先级最高,就用圆括号写清楚优先级