JS基础--JS语法

3,440 阅读8分钟

表达式与语句

表达式

  • 一般来说,表达式都伴随值或返回值的存在。但这并非绝对的
  • 1 + 2表达式的值是 3
  • add(1,2)表达式的值为函数add()的返回值
  • console.log表达式的值为console对象的log函数本身
  • console.log(3)表达式的值是console.log(3)的返回值,但是因为log函数并没有设定返回值,所以JS默认返回undefined
  • 值是值,返回值是返回值两者并不是一个东西。

语句

  • 语句的作用一般具有一定的功能,如:声明,赋值等。但这也并非绝对的
  • var a = 1 这就是一个简单的语句。

表达式和语句的注意点

  1. JS对 大小写是敏感的 ,object和Object是不一样的
  2. JS中大部分的 空格、回车是没有意义 的,而且连续的空格、回车会被默认成1个空格。
  3. 但JS中有一个地方不能加回车,就是函数的return后面,return后面只能在return的同一行写返回的内容,因为return后面的内容并不执行。
  4. JS中的 (逗号,) 与 (分号;):逗号代表该语句还没结束,逗号可以吧多行语句连接成1行语句的效果;而分号在JS中则代表1行语句的结束。

标识符

标识符的规则

  • 第一个字符可以是 1.Unicode字母(包括但不限于英文字母,拉丁字母等都在这个编码中) 2. $ 3. _ 4.中文
  • 后面的字符除了上面的内容还可以是数字
  • 总之,标识符第一个字符不能是数字!!!

标识符不一定是变量名,但最常见的标识符就是变量名

// 一些怪异的变量名
var _ = 1
var $ = 2
var _____ = 6
var 你好 = 'hello'

注释

JS的注释有两种:单行注释和多行注释

// 单行注释

/*
    多行注释
    多行注释
*/

优秀的注释

  1. 分享开发过程踩坑的经验,前人种树后人乘凉。
  2. 开发过程中遇到的bug
  3. 特殊需求

区块(代码块)block

区块常常和if/while/for合用

// {} 包裹的就是一个区块
{
    let a = 1
    let a = 2
}

if语句

if else语句结构

if(判断条件的表达式){语句1}else{语句2} 

if(){} else{} 语句整体只是“一句语句”

else if的原理

   if else 后面的区块 {} 的语句“只有一句”的时候是可以省略的。

// else if 的原理
if(判断1){
    语句1
}else{ // 因为else后面的 {} 中只有一个 if else 语句,所以可以省略 {} 
    if(判断2){
        语句2
     }else {
        语句3
     }
}

// 省略 {} 后,就是常见的 else if 结构
if(判断1){
    语句1
}else if(判断2){
        语句2
}else{
    语句3
}

  只有在使用 else if 的时候才建议省略 {} 其他时候都不建议省略。

  “只有一句”不是“只有一行”,一行里面可以有多个语句(通过 分号; 即可实现)

let a = 1
if(a ===1 )
    if(a<2) // 这是一句语句
        console.log(a) // 这是另一句语句,其实缩进是和 if(a ===1 ) 平级的,人造坑
// 因为 {} 省略后只会关注后面的第一行语句,所以 console.log(a) 并不在 if(a ===1 ) 代码块下面
// console.log(a) 和 if(a ===1 ) 是平级的,执行完 if(a ===1 ) 就执行console.log(a)
// 所以最终结果会输出 1 

  可以通过过 逗号, 来实现多行语句合并成一行语句

//通过过 逗号, 来实现多行语句合并成一行语句
let a  = 1
if(a === 1)
    console.log('a'),console.log('b')
// 因为 console.log('a'),console.log('b') 使用逗号隔开,所以这是一行语句
// 因此结果会输出 a b

推荐的2种 if 语句写法

// 第一种
if (表达式) {
    语句
} else if (表达式) {
    语句
} else {
    语句
}
// 第二种
function fn({
    if (表达式) {
        return 表达式
    }
    if (表达式) {
        return 表达式
    }
    return 表达式
}

switch语句

switch语法

  switch语句整体分4部分:switch部分,case部分(所有case),执行体部分(所有执行体),break。

switch执行顺序:

  1. 将switch部分中传入的变量和case部分的值进行比对
  2. 不相等则比对下一个case部分,直至匹配到相等的case,或switch语句全部结束。
  3. 相等则进入最近的执行体执行一系列的语句,直到遇到一个break
  4. 遇到break退出switch
// 这个例子 如果 fruit = 'lemon' 那么最后输出的是 'lemon or orange' 和 'peach',原因请关注break
switch (fruit) {
            case 'banana':
                console.log('banana')
                break
            case 'apple':
                console.log('apple')
                break
            case 'lemon':
            case 'orange':
                console.log('lemon or orange')
            case 'peach':
                console.log('peach')
                break
}

问号冒号表达式(三元表达式)

语法&使用

三元表达式其实就是 if 语句的简写

// 三元表达式语法
(表达式1)? (表达式2) : (表达式3)

// 使用例子:求绝对值
let a = -1
let abs
// 三元表达式
abs = a>0? a : -a
console.log(abs)

// if 语句
if(a > 0){
    abs = a
} else {
    abs = -a
}
console.log(abs)

&& 短路逻辑

&&的执行逻辑

简单来说:在 A&&B&&C&&D的结构下,取第一个假值,或取D;注意是取值,true/false只是取值的一种情况。

&&的常用情况

// 1. console,因为IE浏览器没有console,所以通过&&来实现兼容写法
// 在IE浏览器下,因为没有console,所以直接执行console.log('haha')会出现报错
// 在这种写法下,执行到console便因为是假值,而不会再向后执行,解决报错问题
console && console.log && console.log('haha')

// 2. 并且判断
// 只有 a 在 1~10之间才会 console.log(a)
// a>1 a<10 返回的都是一个布尔值,所以取的也是一个布尔值
if(a>1 && a<10){
    console.log(a)
}

|| 短路逻辑

||的执行逻辑

简单来说:在 A||B||C||D的结构下,取第一个真值,或取D;注意是取值,true/false只是取值的一种情况。

||常用场景

// 只有当 a 小于 1 或 a 大于 10 才会 console.log(a)
if(a<1 || a>10){
    console.log(a)
}

while循环

语法&执行过程

while(表达式){语句}

执行过程:

  1. 判断表达式的真假
  2. 当表达式为真,执行语句,执行完后再判断表达式的真假
  3. 当表达式为假,跳出循环,执行后面的语句

while循环的注意点

  1. 注意循环的指标变量,循环指标(什么时候跳出循环)不要变成死循环
  2. JS浮点数不精确,循环变成死循环
let a 0.1 
console.log(a+0.1) // 多执行几次会发现结果和想象的不一样

while(a<1){
    console.log(a)
    a + 0.1 // 因为浮点数不精确,a最接近1的值是 0.99999999999 而不会 = 1,结果就是造成死循环
}

for 循环

for循环 与 while循环

for循环就是while循环的语法糖,它将while循环必须有的东西都包括进去了,可以有效防止人为疏忽造成的死循环.

for循环语法&执行过程

for(语句1;表达式2;语句3){
    循环体
}

执行过程:

  1. 执行语句1
  2. 判断表达式2
  3. 如果2.记过为真,执行循环体,执行语句3;循环2. 3. 直到 2. 的结果为假
  4. 如果2.结果为假,直接退出循环,执行后面的语句

for循环中的循环指标变量

这里的例子涉及到 setTimeout的执行机制

setTimeout(func,time)函数运行机制   setTimeout(func,time)是在time(毫秒单位)时间后执行func函数。浏览器引擎按顺序执行程序,遇到setTimeout会将func函数放到执行队列中,等到主程序执行完毕之后,才开始从执行队列(队列中可能有多个待执行的func函数)中按照time延时时间的先后顺序取出来func并执行。即使time=0,也会等主程序运行完之后,才会执行。

for var循环 和 for let循环结果不同的原因:

for var循环本身没有块级作用域,所以 var 的指标变量存储在全局变量中,所以当调用的变量的时候,是从全局变量中获取 for let循环中,let可以构造块级作用域,所以指标变量存储在每次循环的块级作用域中,调用变量的时候从块级作用域中获取

for(var a = 1;a<5;a++){   
        console.log(a)
} // 输出 0 1 2 3 4 

for(var a = 1;a<5;a++){
    setTimeout(()=>{        
        console.log(a)
    },0) 
} // 输出5个5

for(let a = 1;a<5;a++){
    setTimeout(()=>{        
        console.log(a)
    },0)
} // 输出 0 1 2 3 4

break&continue

break:跳出整体循环(循环嵌套下,跳出的是离break最近的那个循环)

continue: 跳出本次循环,直接进入下次循环

label语句(标记语句)

label是什么?与对象的区别

MDN:标记就是在一条语句前面加个可以引用的标识符。标记语句可以和 break 或 continue 语句一起使用。可以让 break 或 continue基于标记而不是当前循环

// label 
foo:{
    console.log(1)
    break foo;
    console.log('break了。本行不输出')
}
console.log(2) // 最终输出 1 2

// 这是一个代码块,代码块内是一个标签,标签的内容是 1;而不是对象
{
    foo:1
}
// 这才是对象
var a = {
    foo:1
}