“它的优秀之处并非原创,它的原创之处并不优秀”
——JS之父对JS的评价
表达式与语句
表达式
用于取值
- 1 + 2表达式的值为3
- add(1,2)表达式的值为函数的返回值,只有函数有返回值
- console.log表达式的值为函数本身
- console.log(3)表达式是返回值是多少?
- 返回值:undefined
- 打印出来的东西是3
语句
用于改变环境(声明、赋值)
语句:变量 + 表达式 ,也可以单纯定义一个空变量
var a = 1 就是一个语句
二者区别
- 表达式一般都有值,语句可能有也可能没有
- 语句一般会改变环境
- 上述两句话并不绝对
JS的大小写敏感
空格
- 大部分空格没有实际意义
- 大部分时候加回车没也有影响
- 只有一个地方不能加回车,那就是return后面
- return后面加回车,会被自动补充一个undefined
标识符
规则
- 第一个字符,可以是Unicode字母或$或_或中文
- 后面的字符,除了上述之外,还可以是数字(数字不能放开头)
- 不能与JS的关键字重名,也尽量不要与JS的保留字重名
上图来自JS标识符、关键字和保留字
if…else
语法
if(表达式) {
语句1</br>
}else if(表达式) {
语句二
}else {
语句三
}
{} 在语句只有一句时可以省略,但最好别这样做
一些易错情况
a =2
if(a = 1){
console.log('a是1')
}else{
console.log('a不是1')
}
这里打印出来的内容为 a是1, 原因是if(a = 1)中已经把a赋值为1,
所以正确的判断方式应该是if(a === 1),这样才能打印出 a不是1
a =2
if(a === 2)
console.log('a')
console.log('a等于2')
这里只会打印出 a等于2 , 因为省略了{}后if只会管到离它最近的第一句
同理:
a =2
if(a === 2)
console.log('a');console.log('a等于2')
也只会打印出 a等于2 ,if只会管到 ;之前的内容
而把上述改为console.log('a'),console.log('a等于2'),打印出来的应该是 undefined
switch
语法
switch (fruit){
case "banana":
// ...
break;
case "apple":
// ...
break;
default;
// ...
}
注意:不要省略上述break,不然会自动往下执行,如"banana"处不写break,会自动执行到"apple"处,直到遇到break为止
为什么这样设计?
起初是为了实现多选
但实现多选其实可以用更为简单的语句,这也是JS的一个糟粕之处
问号冒号表达式
语法
表达式1?表达式2:表达式3
用于简化 if else 里面只有一个表达式的情况
如
function max(a,b){
if(a>b)return a;
else return b;
}
简化为:
function max(a,b){
return a>b?a:b
}
短路逻辑
&&
A&&B
前一个值为假则返回假,前面为真则看后面一个值,都为真则返回最后一个值
如:判断f1是否存在
if(window.f1){
console.log('f1存在')
}
等价于
window.f1 && console.log('f1存在')
A && B && C && D 取出现的第一个价值,或D
||
与上方相反,取第一个真值
常用与给一个变量设定保底值
a = a || 100
等价于
if (a) {
a = a
} else {
a = 100
}
如果a存在,那么a就等于它本身,不存在则把a赋值为100
while
语法
while(表达式){语句}
- 判断表达式的真假
- 当表达式为真,执行语句,执行完再判断表达式的真假
- 当表达式为假,执行后面的语句
一个奇怪的例子
let a = 0.1;
while (a !== 1) {
console.log(a)
a = a + 0.1
}
执行这个循环,程序很可能会进入死循环,是由于浮点数的计算并不精确,如下图
for
语法
for(语句1;表达式2;语句3){ 循环体 }
- 先执行语句1
- 然后判断表达式2
- 为真,执行循环体,然后执行语句3
- 为假,直接退出循环,执行后面的语句
一些易错点
for (var i = 0; i < 5; i++) {
console.log(i)
}
执行完循环之后,i的值应该是5,因为在打印出4之后,i还需执行一次i++才能退出循环
for (var i = 0; i < 5; i++) {
setTimeout(()=>{
console.log(i)
}, 0)
}
这里打印出的内容应该是 5个5
我们已知上一段代码执行完后i的值是5,而setTimeout意思为过一段时间再执行,
所以这段代码其实就是等到for执行完毕后,再打出i的值,而上述过程中for执行了5次,所以最后会打出5个5
需把这段代码的var改成let之后,打印出的内容才会是1,2,3,4
break和continue
- break 跳出当前所有循环
for (var i = 0; i < 10; i++) {
if(i%2===1){
break
}
}
找出10以内最小奇数
- continue 跳过本次循环,下次继续(类似于斗地主中的"过")
for (var i = 0; i < 10; i++) {
if(i%2===1){
continue
}else{
console.log(i)
}
}
找出10以内的双数
一个易错点
for (var i = 0; i < 10; i++) {
for (var j = 101; j < 110; j++) {
if (i===5) {
break;
}
}
console.log(i)
}
这里会打印出数字0到9,因为break只会跳出离它最近的一个for循环
label
{
a:1
}
这不是一个对象,
这是一个代码块,其意为代码块里有一个label,a:1,它表示这个标签是a,a的值为1