语言基础
语法
区分大小写
标识符
- 首字符为字母、下划线、美元符号
- 建议使用驼峰大小写
- 关键字、保留字、true、false、null不能为标识符
注释
- 单行注释
//
- 块注释
/**/
- 单行注释
严格模式
- 加一行
"use strict"
- 是一个预处理指令
- 加一行
语句
可以不分号结束,由解析器决定结尾,但建议都手动自己加分号
大括号里是代码块
变量
var
- 函数级作用域
- 作用域提升
- 重复声明不报错
- 全局声明的变量成为window对象属性
let
块级作用域
没有提升,有暂时死区TDZ
当程序流程进入新的作用域(module、function、block)进行实例化时,在此作用域中,用let、const声明的变量会先在作用域中被创建,但此时还未进行词法绑定,所以还不能被访问,此时访问会抛出错误。在这运行流程一进入作用域创建变量,到变量开始可被访问之间的一段时间,就称之为TDZ(暂时死区)。
let x = 'outer value' function func () { // 这里会产生 TDZ for x console.log(x) // TDZ期间访问,产生ReferenceError错误 let x = 'inner value' // 对x的声明语句,这里结束 TDZ for x } func()
不能重复声明
混用
var
和let
,重复声明会报错全局声明不是window对象的属性
const
- 声明同时必须初始化
- 初始化后不能修改
- 不能修改仅限于常量的引用
- 想让整个对象都不能修改,可以使用
Object.freeze()
- 想让整个对象都不能修改,可以使用
- 不能用于声明会自增的迭代变量
数据类型
六种简单数据类型、一种复杂数据类型(Object)。可以使用typeof
来确定任意变量的数据类型,它返回一个字符串
Undefined
类型
当使用var
或let
声明了变量但没有初始化时,就相当于给变量赋予了undefined
值。在对未初始化的变量调用typeof
时,返回的结果是"undefined"
,但对未声明的变量调用它时,返回的结果还是"undefined"
Null
类型
null
值表示一个空对象指针,这也是给typeof
传一个null
会返回"object"
的原因。任何时候,只要变量要保存对象,而当时又没有那个对象可保存,就要用null
来填充该变量
Boolean
类型
两个字面量true、false
要将一个其他类型的值转换为布尔值,可以调用特定的Boolean()
转型函数,Boolean()
转型函数可以在任意类型的数据上调用,而且始终返回一个布尔值。
NaN
返回false
Number
类型
- Number类型使用IEEE754格式表示整数和浮点值。
- 整数也可以用八进制或十六进制字面量表示。如果字面量中包含的数字超出了应有的范围,就会忽略前缀的零,后面的数字序列会被当成十进制数
- 正零和负零在所有情况下都被认为是等同的
浮点数
- 数值中必须包含小数点,而且小数点后面必须至少有一个数字,没有数字或只有0,则会变成整数
- 科学计数法,数值(整数或浮点数)后跟一个大写或小写的字母e,再加上一个要乘的10的多少次幂
- 精度最高达17位小数,算术计算有时会出现偏差,典型例子:
0.1+0.2==0.3
是false
值的范围
- 最小值
Number.MIN_VALUE
-Infinity
Number.POSITIVE_INFINITY
- 最大值
Number.MAX_VALUE
Infinity
Number.NEGATIVE_INFINITY
- 最小值
NaN
不是数值
- 0、+0、-0相除会返回
NaN
,任何涉及NaN
的操作均返回NaN
,NaN
不等于包括NaN
在内的任何值 isNaN()
函数。该函数接收一个参数,可以是任意数据类型,然后判断这个参数是否“不是数值”。- 首先会调用对象的
valueOf()
方法,然后再确定返回的值是否可以转换为数值 - 如果不能,再调用
toString()
方法,并测试其返回值
- 首先会调用对象的
- 0、+0、-0相除会返回
数值转换
Number()
- 布尔:0、1
- 数值:返回
null
:0undefiner
:NaN
- 字符串
- 正负号+数字字符,转换回十进制数值
- 字符串前含有十六进制格式(
0xf
),返回这个十六进制对应的十进制 - 空字符串:0
- 其他字符情况:
NaN
- 对象
- 调用
valueOf()
方法,再按上述规则转换,如果转换为NaN
,则调用toString()
方法,再按字符串规则转换
- 调用
parseInt()
- 如果第一个字符不是数值字符、加号或减号,parseInt()立即返回NaN
- 如果是,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符
- 字符串以”0x”开头,就会被解释为十六进制整数
- 以”0”开头,且紧跟着数值字符,在非严格模式下会被某些实现解释为八进制整数。
- parseInt()也接收第二个参数,用于指定底数(进制数)。
parseFloat()
- 与
parseInt()
函数相似,从位置0开始检测每个字符。同样,它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。 - 始终忽略字符串开头的零
- 十六进制数值始终会返回0。因为parseFloat()只解析十进制值,因此不能指定底数
- 与
String
类型
双引号、单引号、反引号
- 以某种引号作为字符串开头,必须仍然以该种引号作为字符串结尾。
- 字符串的长度可以通过其
length
属性获取 - 字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量
- 字符串值也有
toString()
方法,该方法只是简单地返回自身的一个副本,null
和undefined
值没有toString()
方法 - 模板字面量保留反引号内部的空格,可以跨行定义字符串
字符串插值
- 模板字面量不是字符串,而是一种特殊的JavaScript句法表达式,只不过求值后得到的是字符串
- 所有插入的值都会使用
toString()
强制转型为字符串,而且任何JavaScript表达式都可以用于插值。嵌套的模板字符串无须转义
标签函数
- 会接收被插值记号分隔后的模板和对每个表达式求值的结果。
- 接收到的参数依次是原始字符串数组和对每个表达式求值的结果。
原始字符串
- 可以直接获取原始的模板字面量内容(如换行符或Unicode字符),而不是被转换后的字符表示
- 默认的
String.raw
标签函数
Symbol
类型
符号实例是唯一、不可变的,用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。符号就是用来创建唯一记号,进而用作非字符串形式的对象属性。
使用
Symbol()
函数初始化,可以传入一个字符串参数作为对符号的描述,字符串参数与符号定义或标识完全无关Symbol()
函数不能与new关键字一起作为构造函数使用。这样做是为了避免创建符号包装对象- 确实想使用符号包装对象,可以借用Object()函数
全局符号注册表
如果运行时的不同部分需要共享和重用符号实例,那么可以用一个字符串作为键,在全局符号注册表中创建并重用符号。
方法:
Symbol.for()
- 都执行幂等操作
- 检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续使用相同字符串的调用同样会检查注册表,发现存在与该字符串对应的符号,然后就会返回该符号实例。
全局注册表中的符号必须使用字符串键来创建,所以参数都会转换成字符串
Symbol.keyFor()
来查询全局注册表- 接收符号,返回该全局符号对应的字符串键。如果查询的不是全局符号,则返回
undefined
。 - 如果传给
Symbol.keyFor()
的不是符号,则该方法抛出TypeError
- 接收符号,返回该全局符号对应的字符串键。如果查询的不是全局符号,则返回
凡是可以使用字符串或数值作为属性的地方,都可以使用符号
Object.getOwnPropertyNames()
返回对象实例的常规属性数组Object.getOwnPropertySymbols()
返回对象实例的符号属性数组Object.getOwnPropertyDescriptors()
会返回同时包含常规和符号属性描述符的对象Reflect.ownKeys()
会返回两种类型的键
常用内置符号
Symbol.asyncIterator
- 返回对象默认的
AsyncIterator
。由for-await-of
语句使用 - 循环时,它们会调用以
Symbol.asyncIterator
为键的函数,并期望这个函数会返回一个实现迭代器API的对象
- 返回对象默认的
Symbol.hasInstance
- 该方法决定一个构造器对象是否认可一个对象是它的实例。由
instanceof
操作符使用 - instanceof操作符可以用来确定一个对象实例的原型链上是否有原型
- 这个属性定义在Function的原型上
- 该方法决定一个构造器对象是否认可一个对象是它的实例。由
Symbol.isConcatSpreadable
- 数组对象
- 默认:打平到已有数组
- true:打平到已有数组
- false:将整个数组对象追加到数组末尾
- 类数组对象
- 默认:将对象追加到数组末尾
- true:打平到已有数组
- false:将对象追加到数组末尾
- 不是数组,也不是类数组
- 默认:将对象追加到数组末尾
- true:忽略
- false:将对象追加到数组末尾
- 数组对象
Symbol.iterator
- 该方法返回对象默认的迭代器。由
for-of
语句使用
- 该方法返回对象默认的迭代器。由
Symbol.match
- 用正则表达式去匹配字符串。由
String.prototype.match()
方法使用
- 用正则表达式去匹配字符串。由
Symbol.replace
- 替换一个字符串中匹配的子串。由
String.prototype.replace()
方法使用
- 替换一个字符串中匹配的子串。由
Symbol.search
- 返回字符串中匹配正则表达式的索引。由
String.prototype.search()
方法使用
- 返回字符串中匹配正则表达式的索引。由
Symbol.species
- 作为创建派生对象的构造函数
- 用Symbol.species定义静态的获取器(getter)方法,可以覆盖新创建实例的原型定义
Symbol.split
- 该方法在匹配正则表达式的索引位置拆分字符串。由
String.prototype.split()
方法使用
- 该方法在匹配正则表达式的索引位置拆分字符串。由
Symbol.toPrimitive
- 该方法将对象转换为相应的原始值。由
ToPrimitive
抽象操作使用
- 该方法将对象转换为相应的原始值。由
Symbol.toStringTag
- 该字符串用于创建对象的默认字符串描述。由内置方法
Object.prototype.toString()
使用 - 通过
toString()
方法获取对象标识时,会检索由Symbol.toStringTag
指定的实例标识符,默认为"Object"
。内置类型已经指定了这个值,但自定义类实例还需要明确定义
- 该字符串用于创建对象的默认字符串描述。由内置方法
Object
类型
就是一组数据和功能的集合,通过new操作符后跟对象类型的名称来创建
constructor
- 创建当前对象的函数
hasOwnProperty(propertyName)
- 用于判断当前对象实例上是否存在给定的属性
isPrototypeOf(Object)
- 判断当前对象是否为另一个对象的原型
propertyIsEnumerable(propertyName)
- 判断给定的属性是否可以使用
for-in
语句枚举
- 判断给定的属性是否可以使用
toLocaleString()
- 返回对象的字符串表示,该字符串反映对象所在的本地化执行环境
toString()
- 返回对象的字符串表示
valueOf()
- 返回对象对应的字符串、数值或布尔值表示。通常与
toString()
的返回值相同。
- 返回对象对应的字符串、数值或布尔值表示。通常与
流控制语句
if
do-while
while
for
for-in
- 用于枚举对象中的非符号键属性
for-of
- 用于遍历可迭代对象的元素
- 标签语句
- 主要用于嵌套循环
- 和c++的goto差不多
break、continue
switch
理解函数
- function关键字声明,后跟一组参数,然后是函数体
- 通过函数名来调用函数,要传给函数的参数放在括号里
- 不需要指定是否返回值。任何函数在任何时间都可以使用return语句来返回函数的值,用法是后跟要返回的值