number 运算
- 加减乘除
- 余数 x % 7
- 指数 x ** 3
- 自增自减 x++ / ++x / x-- / --x
- 求值运算符 +x
- 负数运算符 -x
- string 运算:连接运算 '123' + '456' 注意一下,其中除法不能除以0:
9/0=Infinity(正无穷大)
-9/0=Infinity(负无穷大)
10 % 7 = 17 % 7 余数有个规律,两个数相隔差7,那么他们除以7的余数会相等
但是,-1%7并不会等于6%7而是-1
指数: 7的平方 = 7 ** 2
自增: n在前,值为前;n在后,值为后(n为任意数值)
let a = 1
let b = 2
a++的值为1
++a的值为2
b--的值为2
--b的值为1
求值运算符 +x:只是求值。。不会变正数
负数运算符 -x:正数变负数,负数变正数
string运算 '123' + '456',只支持+号运算符
1 + '2' = '12'其他语言中,数字和字符串一般不能相加, 但是js是个可以。它会先把1变成字符串'1',然后再相加
1 + '2' = '1' + '2' = '12'
如果一个数字和字符串相加,那么js会先把数字变成字符串再相加。
但是,减号则又是另一种情况,字符串是不支持减号的 '2' - 1 = 1
'2'会变转换成数字2,再减去1,然后得出一个数字1
-
尽量少用自增自减 因为容易你和别人都记错
-
不同类型不要加起来 把 1 和 '2' 加起来是几个意思
比较运算符
>
<
>=
<=
== //相等(模糊相等)
!= //不等(不模糊相等)
=== //全等
!== //不全等
JS三位一体
0 == []
0 == '0'
0 == '\t'
//但是右边三个互不相等
- 注意! 永远不要使用 ==!
用 === 代替
== 的问题在于,它总是自作聪明(自动类型转换)
- x == y 真值表(了解即可,永远不要用==)
令人难以理解
[]==false但不是 falsy
[]==false但{}==true
[[]]==false
x === y 真值表
没有任何费解
- 基本类型看值是否相等
- 对象看地址是否相等
[] !== [] //false,因为空数组地址不同 []/*#101*/ !== []/*#108*/
{} !== {} //false,理由同上
NaN !== NaN(唯一特例,强行记忆一下) NaN是个数字,但是不相等
布尔运算符
- 或且非
|| //或
&& //且
! //非
- 短路逻辑 &&短路逻辑:
console = undefined/{} //假设console不存在或者被占用,
那么console.log就会报错
if(console){
if(console.log){
console.log('hi')
}
}
//这样写的话,就不会报错,如果console不存在的话第一层就不通过,
如果console存在,但是却被其他值占用,那么第二层console.log也不通过,
这种写法叫“防御性编程”
console && console.log && console.log('hi')
//可以简写成这样,以防 console 不存在报错
||短路逻辑:
a = a || 100 (100是a的保底值)
function add(n){
n = n || 0 //相当于if(!n){n=0}else{n=n},n不存在为0,存在为n
return n+1
}
//但是这种写法有一个bug,当n等于5个falsy值的时候,都会让n为假,比如''
//所以js除了一个新语法代替它
function add(n=0){ //意思是如果n为null或undefined的时候,n = 0
return n+1
}
add('') //值为'1' , ''+1 = '1'
add(null/undefined) //1
add(NaN) //NaN
二进制运算符
- 或|、与&、否~
0b1111 | 0b1010
//15
(0b1001 | 0b1111).toString(2) //要想显示成二进制数,就调用toString
//"1111"
-
| 两个位都为0,则结果为0,否则为1
-
& 两个位都为1,则结果为1,否则为0
0b1111 & 0b1010
//10
- ~ 运算符是对位求反,1变0, 0变1,也就是求二进制的反码
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// 3的二进制表示为: 00000000 00000000 00000000 00000011
// -----------------------------
// 1反码二进制表示: 11111111 11111111 11111111 11111110
// 由于第一位(符号位)是1,所以这个数是一个负数。JavaScript 内部采用补码形式表示负数,
即需要将这个数减去1,再取一次反,然后加上负号,才能得到这个负数对应的10进制值。
// -----------------------------
// 1的反码减1: 11111111 11111111 11111111 11111101
// 反码取反: 00000000 00000000 00000000 00000010
// 表示为10进制加负号:-2
console.log(~ 1) // -2
简单记忆:一个数与自身的取反值相加等于-1。
- 异或^
(0b0111 ^
0b1010).toString(2)
//"1101"
^ 两个位相同,则结果为0,否则为1
- 左移<< 和 右移>>
(0b0001 << 1).toString(2) //0010
"10"
(0b0010 >> 1).toString(2) //0001
"1"
(0b0011 >> 1).toString(2) //0001右边1会被蹭掉
"1"
(0b0011 << 1).toString(2) //0110空位会自动补0
"110"
头部补零的右移运算符 >>> ,基本跟上面的右移动一样
平时工作很少用,就是为了应付面试
使用与运算符判断奇偶
代码:
偶数 & 1 = 0
奇数 & 1 = 1
使用~, >>, <<, >>>, |来取整
代码:
console.log(~~ 6.83) // 6 ,两次取反得到数字的正数部分
console.log(6.83 >> 0) // 6 ,左移0位取整...
console.log(6.83 << 0) // 6 ,右移0位取整...
console.log(6.83 | 0) // 6 ,| 两个位都为0,则结果为0,否则为1。
与0进行或运算,等于自身。。
console.log(6.83 >>> 0) // 6
//这些运算都会抹除小数部分
使用^来交换 a b 的值
代码:
var a = 5
var b = 8
a ^= b //a ^= b意思是a = a ^ b
b ^= a //b = b ^ a
a ^= b //a = a ^ b
console.log(a) // 8
console.log(b) // 5
点运算符
- 语法 对象 . 属性名 = 属性值
- 作用 读取对象的属性值 / 设置对象的属性值
- 有个疑问
不是对象,为什么也可以有属性?比如
'a-b-c'.split('-')
因为 . 前面如果不是对象就临时创建一个封装对象,然后对象里面有原型,原型里面有split,执行完了以后,自动删除这个临时的对象
再比如,
let a = 1
a.toString() //'1' ,1不是对象,为啥会得到'1'的值
//当js发现a不是对象的时候,会临时创建一个a1
a1 = new Number(a)
//然后执行toString
a1.toString() //'1'
a1.valueOf() //为啥是'1'?因为a1的值为1
//执行完toString后会删除a1
a1 = null
用内存图表示一下,
JS 有特殊逻辑,点前面不是对象,就把它封装成对象
- number 会变成 Number 对象
- string 会变成 String 对象
- bool 会变成 Boolean 对象 程序员从来不用这三种对象,只用简单类型
void 运算符 (了解一下)
- 语法 void 表达式/语句
- 作用 求表达式的值,或执行语句
然后 void 的值总是为 undefined
- 需求
<a href="http://example.com" onclick="f(); return false;">点击</a>
return 假值可以阻止默认动作
<a href="javascript: void(f())">文字</a>
改用 void 可以炫技
逗号运算符
- 语法 表达式1, 表达式2, ..., 表达式n
- 作用 将最后一个值作为整体的值
- 使用
let a = (1,2,3,4,5)
那么 a 的值就是 5
let f = (x) => (console.log('平方值为'), x*x)
注意上面的括号不能省
运算符优先级
优先级是什么?
- 不同运算符
1 + 2 * 3
是先算(1 + 2) * 3
还是 1 + (2 * 3)
if(!a === 1)
是先算(! a) === 1
还是 ! (a === 1)
总结一句话,圆括号优先级最高,比如
if((!a) === 1) //则先算!a
if(!(a === 1)) //就先算a === 1
- 相同运算符 从左到右 a + b + c
从右到左 a = b = c = d
let a,b,c,d
a = b = c = d
//等价于
a = (b = (c = (d = 2))) //圆括号优先级最高
优先级就是先算什么后算什么
- 技巧 圆括号优先级最高