《JavaScript 语言精粹》语法篇

365 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

《JavaScript 语言精粹》 第二章语法读完后的一些笔记摘录

这一章节主要讲解了 JS 的精华部分的语法,并且简要的概述了 JS 的语言结构。

空白

  1. 空白可能表现未被格式化的字符活注释的形式。空白通常没有意义,但有时候必须要用它来分割,不然就合并成一个字符了。
    // 如果 var 和 that 直接没有空格就会变成 varthat 
    var that = this;
  1. 注释
  • 以 /* */ 包围的形式
  • 以 // 开头的形式

标识符

标识符就是给变量、方法名、参数、属性名、标记、语句起名字的符号。

  • 由字母、下划线、数字以及 $ 组成的符号
  • 不能以数字开头
  • 区分大小写
  • 标识符中不能带有空格
  • 不能使用 JS 的保留关键字

以下是 JavaScript 中最​​重要的保留关键字(按字母顺序):

abstractelseinstanceofsuper
booleanenumintswitch
breakexportinterfacesynchronized
byteextendsletthis
casefalselongthrow
catchfinalnativethrows
charfinallynewtransient
classfloatnulltrue
constforpackagetry
continuefunctionprivatetypeof
debuggergotoprotectedvar
defaultifpublicvoid
deleteimplementsreturnvolatile
doimportshortwhile
doubleinstaticwith

数字

JS 只有一种数字类型,由64位的浮点数表示,和 Java 的 double 数字类型一样。

  • 没有分离出整数类型,所以 1 和 1.0 值是相等的
  • 避免了短整型的溢出问题
  • 避免了一大堆因数字类型导致的问题
  • 100 = 1e2
  • 负数用 - 加数字结构表示,-100
  • NaN 是一个数值,表示一个不能产生正常结果的运算结构。NaN 不等于任何值,包括自己,所以可以通过 X === X 是 false 来判断 X 变量是NaN

扩展 如何来检测数据是否是 NaN

  1. 通过与自身全等比较返回值是false,例如:x === x // false
  2. 通过 isNaN() 函数来判断,但是这个函数有Bug,只是判断了是不是一个数值。所以我们可以从新写个方法判断
isNaN(NaN) // true

// 下面三个应该返回 false 才对
isNaN('A String'); // true 
isNaN(undefined); // true 
isNaN({}); // true

// 可以从新写一个方法来替代 isNaN
let isNaNMethod = (val)=>{
   return typeof val === 'number' && isNaN(val)
}
isNaNMethod(NaN) // true
isNaNMethod(undefined) // false
  1. Number.isNaN()这个函数就是修复了 isNaN() 的缺陷

字符串

  • 创建字符串字面量可以用一对单引号或者一对双引号或者es6的字符串模板包裹
  • 可以包含一个或者多个字符
  • 反斜杠是转义符,将原本有特殊含义的转义成字符串
  • JS 创建的时候 Unicode 是一个16位字符集,所以 JS 中所有的字符都是16位的
  • 字符串是不可变的,一旦创建了就不能修改。

语句

一个编译单元包含一组可执行的语句。JS 的语句就是发送给浏览器的命令。语句有以下几种:

  • var 声明语句
  • function 定义一个函数
  • 条件判断语句,if、switch
  • 循环语句,while、do...while、for、for..in
  • 强制推出语句,return、break、throw、continue
  • try ... catch 捕获异常语句
  1. if 语句
    只有当 expression 表达式为 true 时候才会执行后面的代码块,否则就走 else 分支
    if(expression) {
    
    } else { }
  1. switch 语句
    switch执行一个多路分支,它把表达式的值与所有的 case 的条件匹配,并且是精准匹配,当找到一个匹配上了,就会执行 case 从句中的语句,否则就会走 default 中的语句。为了防止执行下一个 case 分支,可以再语句后面使用 break 强制推出 switch
    switch(n) { 
        case 1: 执行代码块 1 
            break; 
        case 2: 执行代码块 2 
            break; 
        default: 
            与 case 1case 2 不同时执行的代码 
            break;
    }
    
    switch(n) { 
        case 1: 
        case 2: 
            执行满足12的代码块 
            break; 
        default: 
            break;
    }
  1. while 语句
    while 语句执行一个简单的循环,如果表达式的值返回 false 则终止循环,反之为 true 则一值执行下去。(一定要判断好终止条件,不然很容易死循环)\color{red}{(一定要判断好终止条件,不然很容易死循环)}
    var i = 10
    while (i--) {
        console.log(i)
    }
  1. do...while 语句
    do...while 语句与 while 语句类似,唯一的区别就是会先执行一次代码块,再进行条件判断
    var i = 0
    do {
        console.log(i)
        i++
    } while (i < 5)
  1. for 循环语句
    由三个可选从句控制:初始化从句,条件从句,增量从句。当条件为 false 则会终止循环
    for (初始化; 条件; 增量) {}
    
    for(let i = 0; i < 10; i++) {
        // do
    }
  1. for in 循环语句
    forin 循环遍历一个对象上的可枚举属性。
    var obj = {name: '小三', age: 18};
    
    for (key in obj) { // key 是属性名称
        console.log('key=' + key)
    }

  1. try ... catch,throw
    try {} 执行代码块,并且捕获代码块中执行抛出的任何异常。catch 会定义一个新的变量来接受抛出的异常对象。在 try 的代码块中执行 throw 语句抛出一个异常,catch 会接收到这个异常。throw 语句中的表达式通常是一个对象字面量,包含一个name 和 message 属性
    try {
        throw('error')
    } catch (e){
        console.log(e) // error
    }
  1. return 语句 return 语句会导致从函数中提前返回,可以指定返回值,没有指定返回值则返回 undefined。return语句后面的代码是不会执行的\color{red}{return 语句后面的代码是不会执行的}。JS 不允许 return 关键字和表达式之间有换行,但是可以用括号
    function a(val){
        return (
            val ? val : 'none
        )
    }
  1. break 语句
    break 语句表示退出,退出一个循环或者 switch 中退出

  2. continue 语句
    continue 语句跳过循环中的当前迭代;

    for (let i = 0; i < 10; i++) {
        if(i === 5){
            continue; // 跳过 i 是5的循环迭代
        }
    }

表达式

常见的表达式

  • 字面量值(比如数字和字符串)
  • 变量
  • 内置的值(true、false、null、undefined、NaN、Infinity 等)
  • 以 new 开头的调用表达式
  • 以 delete 开头的表达式
  • 圆括号中的表达式
  • 以一个前置运算符作为前导的表达式,或者表达式后面跟着一个中置运算符与另一个表达式
  • 三元运算符表达式
  • 函数调用表达式
  • 属性提取表达式

运算符优先级,从高到低

. [] ()提取属性与调用函数
delete new typeof + - !一元运算符
* / %乘法、除法、求余
+ -加法/连接符、减法
>= <= > <不等式运算符
=== !==等式运算符
&&逻辑与
||逻辑或
?:三元

typeof 返回值

  • number
  • string
  • boolean
  • undefined
  • function
  • object

typeof null === 'object'

扩展 为什么 typeof null === 'object'

JavaScript 中不同的对象都是用二进制来表示的,其中会把二进制中的前三位来表示类型,Object 类型的二进制的前三位都是0,null 是 JS 中的一个空指针,底层的二进制表示都是0,所有 typeof 会判断成 object

字面量

  • 对象字面量
    • 可以方便的按指定规格创建对象的表示法
    • 对象的属性值可以是标识符或者字符串
    • 属性的值就是表达式
  • 数组字面量
    • 可以方便的按指定规格创建数组的表示法
    // 对象字面量
    var prop = 'first-name'
    var obj = {
        name: 'abc',
        [prop]: 'efg'
    }
    
    // 数组字面量
    var list = [{name: 'abc'}, 123, 'cc']

函数

  • 函数字面量定义的是函数的值
  • 可以有一个函数名,用于递归调用自己
  • 可以指定一个参数列表,在调用的时候由传递的实际参数初始化
  • 函数主体包括定义变量和语句