JS版本:ES 6是最低要求
表达式和语句
表达式(expression)
- 表达式,指一个为了得到一个值的计算式
- 函数的值也称为返回值 举例:
- 1+2表达式的值是3
- add(1,2)表达式的值为函数的返回值
- console.log表达式的值为函数本身
- console.log(3 )表达式的值是undefined,表达式显示的内容是3
语句(statement)
- 语句是为了完成某种任务而进行的操作
- 语句一般会改变环境(比如声明、赋值)
- 语句以分号或者空格结尾,一个分号或者空格就表示一个语句结束。
- js代码不用写分号不用不用,只有立即执行函数前面需要
- 多个语句可以写在一行内。
- 如果语句间用逗号连接,表示一个语句。
var a = 1 + 3;
这条语句先用var命令,声明了变量a,然后将1 + 3的运算结果赋值给变量a。
表达式和语句的区别
- 只有函数有返回值,函数也有值,函数的值就是他的返回值,但是一般的表达式不能说返回值,只能说值
- 语句主要是用来改变环境的,所以很多语句的值都是undefined,表达式才主要是用来取值的
- 表达式一般都有值,语句可能有可能没有
注:
- JS对大小写敏感
- 大部分空格是没有实际意义的
- 加回车大部分时候也不影响(只有return后边不能加回车)
标识符
标识符(identifier)指的是用来识别各种值的合法名称。最常见的标识符就是变量名,以及后面要提到的函数名。JavaScript 语言的标识符对大小写敏感,所以a和A是两个不同的标识符。
标识符有一套命名规则,不符合规则的就是非法标识符。JavaScript 引擎遇到非法标识符,就会报错。
规则
- 第一个字符,可以是Unicode字母或者$或_或中文
- 后面的字符,除了上边所说,话可以是数字
变量名是标识符
- var _ = 1
- var $ = 2
- var _____ =6 这样用会被打
- var 你好 = 'hi'
- 还有其他格式
合法标识符
arg0
_tmp
$elem
π
不合法标识符
1a // 第一个字符不能是数字
23 // 同上
*** // 标识符不能包含星号
a+b // 标识符不能包含加号
-d // 标识符不能包含减号或连词线
中文是合法的标识符,可以用作变量名。
var 临时变量 = 1;
JavaScript 有一些保留字,不能用作标识符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。
注:报错样式
Uncaught SyntaxError: Unexpected token xxx( 未捕捉的语法错误:xxx不是我们所期待的字符串)
注释
- 定义:源码中被 JavaScript 引擎忽略的部分就叫做注释
- 作用:对代码进行解释
- 写法: 一种是单行注释,用//起头
- 另一种是多行注释,放在/*和*/之间。
// 这是单行注释
/*
这是
多行
注释
*/
注释的分类:
不好的注释:
- 把代码翻译成中文
- 过时的注释
- 发泄不满的注释
好的注释:
- 踩坑注解
- 为什么代码会写得奇怪,遇到什么bug
区块
1.JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。
{
let a=1
let b=1
}
2.对于var命令来说,JavaScript 的区块不构成单独的作用域(scope)。
{
var a = 1
}
a // 1
上面代码在区块内部,使用var命令声明并赋值了变量a,然后在区块外部,变量a依然有效,区块对于var命令不构成单独的作用域,与不使用区块的情况没有任何区别。
3.在 JavaScript 语言中,单独使用区块并不常见,区块往往用来构成其他更复杂的语法结构,比如for、if、while、function等。
条件语句
if结构
1.规则
- 先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。
- 所谓布尔值,指的是 JavaScript 的两个特殊值,true表示真,false表示伪。
- 如果表达式的求值结果为true,就执行紧跟在后面的语句;如果结果为false,则跳过紧跟在后面的语句。
2.基本形式
if (表达式){
语句
}
3.关于=
- 赋值表达式(=):x=y 把y的值赋给x!一直是true!
- 严格相等运算符(===):x===y x等于y 优先采用
- 相等运算符(==): x===y x等于y
if...else 结构:
if代码块后面,还可以跟一个else代码块,表示不满足条件时,所要执行的代码。
1.规则:
- 先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。
- 如果表达式的求值结果为true,就执行紧跟在表达式后面的语句1;如果结果为false,则执行else里的语句2
2.基本形式
if (表达式){
语句1
}
else{
语句2
}
3.语句1里面可以有嵌套的if...else 结构
var m = 1;
var n = 2;
if (m !== 1)
if (n === 2) console.log('hello');
else console.log('world');
上面代码不会有任何输出,else代码块不会得到执行,因为它跟着的是最近的那个if语句,相当于下面这样。
if (m !== 1) {
if (n === 2) {
console.log('hello');
} else {
console.log('world');
}
}
4.语句2里面可以有嵌套的if...else 结构
// 对一个变量多次进行判断
if (表达式一) {
语句一;
} else {
if (表达式二) {
语句二;
} else {
if (表达式三) {
语句三;
} else {
语句四;
}
}
}
// 去掉一些大括号,等同于
// 最推荐写法
if (表达式一) {
语句一;
} else if (表达式二) {
语句二;
} else if (表达式三) {
语句三;
} else {
语句四;
}
function fn(){
if (表达式) {
return表达式
}
if (表达式) {
return表达式
}
return表达式
}
5.else代码块总是与离自己最近的前面的那个if语句配对。
6.缩进也可以很变态,如面试题常常下套
a=1
if(a===2)
console.log('a')
console.log( 'a等于2')
// a等于2
等同于
a=1
if(a===2){
console.log('a')
}
console.log( 'a等于2')
程序员戒律:使用没有歧义的写法
最推荐的写法
if(表达式){
语句
}else if(表达式){
语句
} else {
语句
}
次推荐写法
function fn(){
if (表达式){
return 表示式
}
if (表达式){
return 表达式
}
return 表达式
}
return包含后面都不执行的意思,所以此时可以省略else,因为else的意思就是如果前面都没执行,就执行else之后的。
switch语句(不推荐)
1.基本结构
switch (fruit) {
case "banana":
// ...
break;
case "apple":
// ...
break;
default:
// ...
}
上面代码根据变量fruit的值,选择执行相应的case。如果所有case都不符合,则执行最后的default部分。
注:
- 大部分时候,省略break,你就完了
- 少部分时候,需要使用break
问好冒号表达式
1.基本形式
(表达式) ? 语句1 : 语句2
2.规则:如果“表达式”为true,则执行“语句1”,否则执行“语句2”
举例:
function max(a,b){
if(a>b)return a;
else return b;
}
//等同于
function max(a,b){
return a>b ? a:b
}
注: 能用问号冒号表达式的时候就不用if...else
&&短路逻辑
也是用来替代if else
A && B && C && D 取第一个假值或D,并不会取true或false
举例:
if(window.f1){
console.log('f1存在')
}
//等同于
window.f1 && console.log('f1存在')
fn && fn()
fn存在就调用fn,不存在就不调用
|| 短路逻辑
A || B || C || D 取第一个真值或D,并不会取true或false
举例:
a||b
//等同于
if(!a){
b
}else{a}
//如果a不存在,就执行b,否则还是a
a = a||100
//如果a存在就是a,如果a不存在就令a为100
//如果变量a存在,变量a就为第一个真值,再把变量a赋值给变量a,a还是a自己
//a不存在,那么第一个a不是真值,就执行最后一句a=100。给a一个保底值。
等同于
if(a){
a=a
} else{
a=100 // 保底值
}
//如果a不存在就令a为100,如果a存在就令a还是为a
等同于
if(!a){
a=100 // 保底值
} else{
a=a
}
循环语句
while(不推荐)
1.基本结构
while (表达式) {循环体语句}
2.规则:
- 判断表达式的真假
- 当表达式为真,执行语句,执行完再判断表达式的真假
- 当表达式为假,执行后面的语句
注意:
容易死循环 (下面的代码将循环100次,直到i等于100为止)
var i = 0; //初始化表达式
while (i < 100) { //判断表达式
console.log('i 当前为:' + i); //循环体语句
i = i + 1; //递增表达式
}
浮点数不精确 (会进入死循环。因为浮点数a永远不会等于1)
while(a !== 1){
console.log(a)
a=a+0.1
}
for循环
1.基本结构
for (初始化表达式; 判断表达式; 递增表达式) {
循环体语句
}
2.规则
- 先执行初始化表达式
- 再判断表达式的真假
- 如果为真,就执行循环体语句,然后执行递增表达式
- 如果为假,就直接退出循环,执行后边的语句
举例:
var x = 3;
for (var i = 0; i < x; i++) {
console.log(i);
}
// 0
// 1
// 2
// 最后循环执行完i=3
上面面代码中,初始化表达式是var i = 0,即初始化一个变量i;判断表达式是i < x,即只要i小于x,就会执行循环;递增表达式是i++,即每次循环结束后,i增大1。
for(var i=0;i<3;i++){
setTimeout(()=>{
console.log(i)
},0)
}
//3个3
/*
i=0满足i<3,所以执行循环体打出i,但要过一会。
以此类推
i=1满足i<3,所以执行循环体打出i,但要过一会。
i=2满足i<3,所以执行循环体打出i,但要过一会。
i=3不满足i<3,结束循环。
for循环不结束,就不算过一会!
现在循环结束了,过一会了,终于要打出i了,而且还要打出三次,因为此时i=3了。所以打出了3个3
*/
所有for循环,都可以改写成while循环
var x = 3;
var i = 0;
while (i < x) {
console.log(i);
i++;
}
break和continue
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行。
break语句用于跳出代码块或循环。
var i = 0;
while(i < 100) {
console.log('i 当前为:' + i);
i++;
if (i === 10) break;
}
//上面代码只会执行10次循环,一旦i等于10,就会跳出循环。
for循环也可以使用break语句跳出循环。
for (var i = 0; i < 5; i++) {
console.log(i);
if (i === 3)
break;
}
// 0
// 1
// 2
// 3
//上面代码执行到i等于3,就会跳出循环。
continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。
var i = 0;
while (i < 100){
i++;
if (i % 2 === 0) continue;
console.log('i 当前为:' + i);
}
//上面代码只有在i为奇数时,才会输出i的值。如果i为偶数,则直接进入下一轮循环。
如果存在多重循环,不带参数的break语句和continue语句都只针对最内层循环。
label
JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
label:
语句
举例:
foo:{
console.log(1);
break foo;
console.log('本行不会输出');
}
//foo是一个标签,表示一个代码块
//1
{
foo:1;
}
//这是一个代码块,代码块里有一个标签foo,标签foo的内容是1