面试中的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}

运算符优先级

圆括号优先级最高,就用圆括号写清楚优先级

comments powered by Disqus