一:运算符
- 算数运算符
运算符 | 描述 |
---|---|
+ | 进行加法运算,如果有字符型,会进行字符串拼接 |
- | 进行减法运算 |
* | 进行乘法运算 |
/ | 进行除法运算 |
% | 进行取余操作 |
++ | 自加操作,位于变量之前时先自加,后参与计算;位于之后则先参与计算再自加 |
- - | 自减操作,位于变量之前时先自减,后参与计算;位于之后则先参与计算再自减 |
- 赋值运算符
运算符 | 描述 | 举例 | 等同于 |
---|---|---|---|
= | 赋值,将等号右边的值赋值给左边的变量 | x=5 | x=5 |
+= | 将变量本身的值加上右边的值的结果赋值给该变量 | x+=5 | x=x+5 |
-= | 将变量本身的值减去右边的值的结果赋值给该变量 | x-=5 | x=x-5 |
*= | 将变量本身的值乘上右边的值的结果赋值给该变量 | x*=5 | x=x*5 |
/= | 将变量本身的值除以右边的值的结果赋值给该变量 | x/=5 | x=x/5 |
%= | 将变量本身的值取余右边的值的结果赋值给该变量 | x%=5 | x=x%5 |
- 比较运算符
运算符 | 描述 | 例子 | 结果 |
---|---|---|---|
== | 等于,比较值的大小,会进行隐式转换 | 5 == “5”, 4==4 | true,true |
=== | 全等于,会比较值的类型 | 5 === “5” | true |
!= | 不等于,会进行隐式转换 | 5 != “5” | false |
!== | 不等于,会比较值的类型 | 5 !== “5” | true |
> | 大于 | ||
< | 小于 | ||
<== | 小于等于 | ||
>== | 大于等于 | ||
? : | 三元运算符,?左边是条件,如果成立就执行中间的代码,不成立就执行 :右边的代码 | 4>3 ? console.log(4) : console.log(3) | 4 |
- 逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
&&会从左到右执行,如果为true就会继续执行,直到遇到false(如果本身不是布尔值,就会转换为布尔值),并且遇到false会立即停止执行,后面的都不会再继续执行,返回值是最后一次执行的结果。
console.log( 1 && 0 && 2) // 0
console.log( 1 && 2 && 3) // 3
1 && false && console.log("这里不会被执行") //后面的console不会执行
|| 也是从左到右执行,如果为false就会继续执行,直到遇到true(如果本身不是布尔值,就会转换为布尔值),遇到true后会停止执行后面的代码,返回值是最后一次执行的结果。
console.log( 0 || false || 2) // 2
console.log( undefined || null || 0) //0
0 || 1 || console.log("这里不会被执行") //后面的console不会执行
二:变量
JavaScript 变量是存储数据值的容器。如果将基本数据类型的值赋值给变量,那么变量直接存储数据值;如果是引用类型,那么变量存储的是该数据的地址。要使用变量,需要使用 var、let 或 const 定义,其中 let 和 const 是 ES6 新增的。
- 使用 var 定义,具有以下特点:
- 具有函数作用域,即在函数内声明了,在整个函数内都是有效的;
- 可以在定义之前使用,但是值为 undefined;(变量提升,以后再说)
- 可以重复定义;
var i = 10;
var i = "hahaha" //是允许的。
但是函数作用域会导致一些问题,如下面的for循环,我们期盼能够打印0到9的数字,但是实际会打印 10 个 10 。因为在 js 中,由于 js 是单线程,所以对于异步操作,会单独放到一个队列里面,等待同步代码执行完毕后再执行异步代码。setTimeout 是一个异步函数,在这个函数执行的时候,for 循环已经执行完毕,此时 i 已经变为10,所以会得到10个10.
for(var i = 0;i <10;i++){
setTimeout(function(){
console.log(i)
},0)
}
- 使用let定义,具有以下特点:
- 具有块级作用域,即使用let定义的变量只在该作用域起作用,可以很好的解决上面使用 var 定义的循环变量导致的问题。如下面的代码,此时就可以得到想要的 0 到 9 的数字,并且在 for 循环外面是拿不到变量 i 的。
for(let i = 0;i <10;i++){
setTimeout(function(){
console.log(i); //0,1,2,3,4,5,6,7,8,9
},0)
console.log(i) //会报错,i is not defined;因为i是使用let定义的,所以只会在定义的那一块代码里起作用。
- 不能重复定义
- 不能在定义之前使用
console.log(a) //会报错
let a = 10;
let a = 20; //会报错
- 使用const定义,具有以下特点:
- 具有所有let的特点
- 定义的是一个常量,无法修改,所以在定义的时候必须给定值,不然会报错。
const i; //报错。Missing initializer in const declaration。
const i =10;
i = 20; //报错。不能修改
const obj = {a:20};
obj.a = 10; //不会报错,可以正常执行。
在以上代码里,可以发现使用const定义的对象是可以进行修改的,这是因为变量存储引用类型时,存储的其实是堆内存的地址,而修改对象本身时是不会修改对象的地址的。所以使用const定义引用类型数据时需要注意。