一、声明
- const 命令:声明常量
- let 命令:声明变量
特点:
- 与
var
定义的区别,不存在变量提升。 - 暂时性死区:变量未定义之前无法使用。
- 不能重复声明。
- 作用域
- 全局作用域
- 函数作用域
- 块级作用域
二、解构赋值
- 字符串解构:
const [a, b, c, d, e] = "hello"
- 数值解构:
const { toString: s } = 123
- 布尔解构:
const { toString: b } = true
- 对象解构
- 形式:
const { x, y } = { x: 1, y: 2 }
- 默认:
const { x, y = 2 } = { x: 1 }
- 改名:
const { x, y: z } = { x: 1, y: 2 }
- 形式:
- 数组解构
- 规则:数据结构具有
Iterator接口
可采用数组形式的解构赋值 - 形式:
const [x, y] = [1, 2]
- 默认:
const [x, y = 2] = [1]
- 规则:数据结构具有
- 函数参数解构
- 数组解构:
function Func([x = 0, y = 1]) {}
- 对象解构:
function Func({ x = 0, y = 1 } = {}) {}
- 数组解构:
注意:
- 匹配模式:只要等号两边的模式相同,左边的变量就会被赋予对应的值
- 解构赋值规则:只要等号右边的值不是对象或数组,就先将其转为对象
- 解构默认值生效条件:属性值严格等于
undefined
- 解构遵循匹配模式
- 解构不成功时变量的值等于
undefined
undefined
和null
无法转为对象,因此无法进行解构
三、字符串扩展
- Unicode表示法:
大括号包含
表示Unicode字符(\u{0xXX}
或\u{0XXX}
) - 字符串遍历:可通过
for-of
遍历字符串 - 字符串模板:可单行可多行可插入变量的增强版字符串
- 标签模板:函数参数的特殊调用
- String.raw():返回把字符串所有变量替换且对斜杠进行转义的结果
- String.fromCodePoint():返回码点对应字符
- codePointAt():返回字符对应码点(
String.fromCodePoint()
的逆操作) - normalize():把字符的不同表示方法统一为同样形式,返回
新字符串
(Unicode正规化) - repeat():把字符串重复n次,返回
新字符串
- matchAll():返回正则表达式在字符串的所有匹配
- includes():是否存在指定字符串
- startsWith():是否存在字符串头部指定字符串
- endsWith():是否存在字符串尾部指定字符串
四、数值扩展
- 二进制表示法:
0b或0B开头
表示二进制(0bXX
或0BXX
) - 八进制表示法:
0o或0O开头
表示二进制(0oXX
或0OXX
) - Number.EPSILON:数值最小精度
- Number.MIN_SAFE_INTEGER:最小安全数值(
-2^53
) - Number.MAX_SAFE_INTEGER:最大安全数值(
2^53
) - Number.parseInt():返回转换值的整数部分
- Number.parseFloat():返回转换值的浮点数部分
- Number.isFinite():是否为有限数值
- Number.isNaN():是否为NaN
- Number.isInteger():是否为整数
- Number.isSafeInteger():是否在数值安全范围内
- Math.trunc():返回数值整数部分
五、对象扩展
- 简洁表示法:直接写入变量和函数作为对象的属性和方法(
{ prop, method() {} }
) - 属性名表达式:字面量定义对象时使用
[]
定义键([prop]
,不能与上同时使用) - 方法的name属性:返回方法函数名
- 取值函数(getter)和存值函数(setter):
get/set 函数名
(属性的描述对象在get
和set
上) - bind返回的函数:
bound 函数名
- Function构造函数返回的函数实例:
anonymous
- 取值函数(getter)和存值函数(setter):
- 属性的可枚举性和遍历:描述对象的
enumerable
- super关键字:指向当前对象的原型对象(只能用在对象的简写方法中
method() {}
) - Object.is():对比两值是否相等
- Object.assign():合并对象(浅拷贝),返回原对象
- Object.getPrototypeOf():返回对象的原型对象
- Object.setPrototypeOf():设置对象的原型对象
- proto:返回或设置对象的原型对象
属性遍历
for-in
:遍历对象自身可继承可枚举
属性Object.keys()
:返回对象自身可枚举
属性键组成的数组Object.getOwnPropertyNames()
:返回对象自身非Symbol
属性键组成的数组Object.getOwnPropertySymbols()
:返回对象自身Symbol
属性键组成的数组Reflect.ownKeys()
:返回对象自身全部
属性键组成的数组
六、数组扩展
- 扩展运算符(…):转换数组为用逗号分隔的参数序列(
[...arr]
,相当于rest/spread参数
的逆运算) - Array.from():转换具有
Iterator接口
的数据结构为真正数组,返回新数组- 类数组对象:
包含length的对象
、Arguments对象
、NodeList对象
- 可遍历对象:
String
、Set结构
、Map结构
、Generator函数
- 类数组对象:
- Array.of():转换一组值为真正数组,返回新数组
- copyWithin():把指定位置的成员复制到其他位置,返回原数组
- find():返回第一个符合条件的成员
- findIndex():返回第一个符合条件的成员索引值
- fill():根据指定值填充整个数组,返回原数组
- keys():返回以索引值为遍历器的对象
- values():返回以属性值为遍历器的对象
- entries():返回以索引值和属性值为遍历器的对象
- 数组空位:ES6明确将数组空位转为
undefined
(空位处理规不一,建议避免出现)
应用:
- 克隆数组:
const arr = [...arr1]
- 合并数组:
const arr = [...arr1, ...arr2]
- 拼接数组:
arr.push(...arr1)
- 代替apply:
Math.max.apply(null, [x, y])
=>Math.max(...[x, y])
- 转换字符串为数组:
[..."hello"]
- 转换类数组对象为数组:
[...Arguments, ...NodeList]
- 转换可遍历对象为数组:
[...String, ...Set, ...Map, ...Generator]
- 与数组解构赋值结合:
const [x, ...rest/spread] = [1, 2, 3]
- 计算Unicode字符长度:
Array.from("hello").length
=>[..."hello"].length
七、函数扩展
- 参数默认值:为函数参数指定默认值
- 形式:
function Func(x = 1, y = 2) {}
- 参数赋值:惰性求值(函数调用后才求值)
- 参数位置:尾参数
- 参数作用域:函数作用域
- 声明方式:默认声明,不能用
const
或let
再次声明 - length:返回没有指定默认值的参数个数
- 与解构赋值默认值结合:
function Func({ x = 1, y = 2 } = {}) {}
- 应用
- 指定某个参数不得省略,省略即抛出错误:
function Func(x = throwMissing()) {}
- 将参数默认值设为
undefined
,表明此参数可省略:Func(undefined, 1)
- 指定某个参数不得省略,省略即抛出错误:
- 形式:
- rest/spread参数(…):返回函数多余参数
- 形式:以数组的形式存在,之后不能再有其他参数
- 作用:代替
Arguments对象
- length:返回没有指定默认值的参数个数但不包括
rest/spread参数
- 严格模式:在严格条件下运行JS
- 应用:只要函数参数使用默认值、解构赋值、扩展运算符,那么函数内部就不能显式设定为严格模式
- name属性:返回函数的函数名
- 将匿名函数赋值给变量:
空字符串
(ES5)、变量名
(ES6) - 将具名函数赋值给变量:
函数名
(ES5和ES6) - bind返回的函数:
bound 函数名
(ES5和ES6) - Function构造函数返回的函数实例:
anonymous
(ES5和ES6)
- 将匿名函数赋值给变量:
- 箭头函数(=>):函数简写
- 无参数:
() => {}
- 单个参数:
x => {}
- 多个参数:
(x, y) => {}
- 解构参数:
({x, y}) => {}
- 嵌套使用:部署管道机制
- this指向固定化
- 并非因为内部有绑定
this
的机制,而是根本没有自己的this
,导致内部的this
就是外层代码块的this
- 因为没有
this
,因此不能用作构造函数
- 并非因为内部有绑定
- 无参数:
尾调用优化:只保留内层函数的调用帧
- 尾调用
- 定义:某个函数的最后一步是调用另一个函数
- 形式:
function f(x) { return g(x); }
- 尾递归
- 定义:函数尾调用自身
- 作用:只要使用尾递归就不会发生栈溢出,相对节省内存
- 实现:把所有用到的内部变量改写成函数的参数并使用参数默认值 箭头函数误区
- 尾调用
函数体内的
this
是定义时所在的对象
而不是使用时所在的对象
- 可让
this
指向固定化,这种特性很有利于封装回调函数 - 不可当作
构造函数
,因此箭头函数不可使用new命令
- 不可使用
yield命令
,因此箭头函数不能用作Generator函数
- 不可使用
Arguments对象
,此对象在函数体内不存在(可用rest/spread参数
代替) - 返回对象时必须在对象外面加上括号
八、正则扩展
- 变更RegExp构造函数入参:允许首参数为
正则对象
,尾参数为正则修饰符
(返回的正则表达式会忽略原正则表达式的修饰符) - 正则方法调用变更:字符串对象的
match()
、replace()
、search()
、split()
内部调用转为调用RegExp
实例对应的RegExp.prototype[Symbol.方法]
- u修饰符:Unicode模式修饰符,正确处理大于
\uFFFF
的Unicode字符
点字符
(.)Unicode表示法
量词
预定义模式
i修饰符
转义
- y修饰符:粘连修饰符,确保匹配必须从剩余的第一个位置开始全局匹配(与
g修饰符
作用类似) - unicode:是否设置
u修饰符
- sticky:是否设置
y修饰符
- flags:返回正则表达式的修饰符
九、Symbol 类型
- 定义:独一无二的值
- 声明:
const set = Symbol(str)
- 入参:字符串(可选)
- 方法
- Symbol():创建以参数作为描述的
Symbol值
(不登记在全局环境) - Symbol.for():创建以参数作为描述的
Symbol值
,如存在此参数则返回原有的Symbol值
(先搜索后创建,登记在全局环境) - Symbol.keyFor():返回已登记的
Symbol值
的描述(只能返回Symbol.for()
的key
) - Object.getOwnPropertySymbols():返回对象中所有用作属性名的
Symbol值
的数组
- Symbol():创建以参数作为描述的
- 内置
- Symbol.hasInstance:指向一个内部方法,当其他对象使用
instanceof运算符
判断是否为此对象的实例时会调用此方法 - Symbol.isConcatSpreadable:指向一个布尔,定义对象用于
Array.prototype.concat()
时是否可展开 - Symbol.species:指向一个构造函数,当实例对象使用自身构造函数时会调用指定的构造函数
- Symbol.match:指向一个函数,当实例对象被
String.prototype.match()
调用时会重新定义match()
的行为 - Symbol.replace:指向一个函数,当实例对象被
String.prototype.replace()
调用时会重新定义replace()
的行为 - Symbol.search:指向一个函数,当实例对象被
String.prototype.search()
调用时会重新定义search()
的行为 - Symbol.split:指向一个函数,当实例对象被
String.prototype.split()
调用时会重新定义split()
的行为 - Symbol.iterator:指向一个默认遍历器方法,当实例对象执行
for-of
时会调用指定的默认遍历器 - Symbol.toPrimitive:指向一个函数,当实例对象被转为原始类型的值时会返回此对象对应的原始类型值
- Symbol.toStringTag:指向一个函数,当实例对象被
Object.prototype.toString()
调用时其返回值会出现在toString()
返回的字符串之中表示对象的类型 - Symbol.unscopables:指向一个对象,指定使用
with
时哪些属性会被with环境
排除
- Symbol.hasInstance:指向一个内部方法,当其他对象使用
应用场景
- 唯一化对象属性名:属性名属于Symbol类型,就都是独一无二的,可保证不会与其他属性名产生冲突
- 消除魔术字符串:在代码中多次出现且与代码形成强耦合的某一个具体的字符串或数值
- 遍历属性名:无法通过
for-in
、for-of
、Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回,只能通过Object.getOwnPropertySymbols
返回 - 启用模块的Singleton模式:调用一个类在任何时候返回同一个实例(
window
和global
),使用Symbol.for()
来模拟全局的Singleton模式
注意
Symbol()
生成一个原始类型的值不是对象,因此Symbol()
前不能使用new命令
Symbol()
参数表示对当前Symbol值
的描述,相同参数的Symbol()
返回值不相等Symbol值
不能与其他类型的值进行运算Symbol值
可通过String()
或toString()
显式转为字符串Symbol值
作为对象属性名时,此属性是公开属性,但不是私有属性Symbol值
作为对象属性名时,只能用方括号运算符([]
)读取,不能用点运算符(.
)读取Symbol值
作为对象属性名时,不会被常规方法遍历得到,可利用此特性为对象定义非私有但又只用于内部的方法