ES6新特性列表
本文转载整理自方方文章:https://fangyinghang.com/es-6-tutorials/
1. 作用域
1.1 块级作用域
块语句(或其他语言的复合语句)用于组合零个或多个语句。该块由一对大括号界定,可以是labelled:
语法:
块声明:
{ StatementList },StatementList:在块语句中分组的语句。标记块声明:LabelIdentifier: { StatementList },LabelIdentifier:用于视觉识别的可选
label或break的目标
通过var声明的变量,没有块级作用域,所设置变量的影响会在超出语句块本身之外持续存在。 换句话说,这种语句块不会引入一个作用域。
相比之下,使用 let和const声明的变量是有块级作用域的。
1.2 块级变量let
let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。let允许你声明一个作用域被限制在 块级中的变量、语句或者表达式。与 var 关键字不同的是, var声明的变量只能是全局或者整个函数块的。 var 和 let 的不同之处在于let是在编译时才初始化(声明let前不可访问,暂存死区)。
就像const 一样,let不会在全局声明时(在最顶部的范围)创建window 对象的属性。
let声明的变量只在其声明的块或子块中可用,这一点,与var相似。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数。
1 | // var声明的变量整个函数作用域内都可以访问 |
暂存死区
与通过
var声明的有初始化值undefined的变量不同,通过let声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致ReferenceError。该变量处在一个自块顶部到初始化处理的“暂存死区”中。如果使用
typeof检测在暂存死区中的变量, 会抛出ReferenceError异常:
1 | function do_something () { |
1.3 块级变量const
常量是块级作用域,很像使用 let 语句定义的变量。常量的值不能通过重新赋值来改变,并且不能重新声明。
const常量更let一样,只不过一旦声明就不能修改值。
- 暂存死区:与let一样
2. 箭头函数
sum = (a, b) => a + bnums.forEach( v => { console.log(v) })- 词法 this,
箭头函数和普通函数区别:
1、箭头函数没有this
2、箭头函数不能使用new调用
3、箭头函数没有arguments参数
3. 参数处理
3.1 默认参数值
函数默认参数允许在没有值或undefined被传入时使用默认形参。
JavaScript 中函数的参数默认是undefined。然而,在某些情况下可能需要设置一个不同的默认值。这是默认参数可以帮助的地方。以前,一般设置默认参数的方法是在函数体测试参数是否为undefined,如果是的话就设置为默认的值。
1 | function multiply(a, b = 1) { |
3.2 剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
语法:function(a, b, ...theArgs) {}
如果函数的最后一个命名参数以...为前缀,则它将成为一个由剩余参数组成的数组,其中从0(包括)到theArgs.length - 1的元素由传递给函数的实际参数提供。在上面的语法中,theArgs将收集该函数的第三个参数(第一个参数被映射到a,而第二个参数映射到b)和所有后续参数。
在上面的语法中,theArgs将收集该函数的第三个参数(第一个参数被映射到a,而第二个参数映射到b)和所有后续参数。
- 剩余参数和
arguments对象的区别- 剩余参数只包含那些没有对应形参的实参,而
arguments对象包含了传给函数的所有实参。 arguments对象不是一个真正的数组,而剩余参数是真正的Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如sort,map,forEach或pop。arguments对象还有一些附加的属性 (如callee属性)。
- 剩余参数只包含那些没有对应形参的实参,而
1 | function sum(...theArgs) { |
3.3 展开运算符
展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。
语法:
函数调用:
myFunction(...iterableObj),等价于apply方式调用myFunction.apply(null, iterableObj),在new表达式中不能使用apply,扩展运算符就很好替换字面量数组构造或字符串:
[...iterableObj, '4', ...'hello', 6]构造字面量对象时,进行克隆或者属性拷贝:
let objClone = { ...obj },作用跟Object.assign()一样,都是浅拷贝,Object.assign()函数会触发 setters,而展开语法则不会
注意:
在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象:
在函数调用时使用展开语法,请注意不能超过 JavaScript 引擎限制的最大参数个数。更多详细信息,请参考:
apply()。
1 | function sum(x, y, z) { return x + y + z; } |
4. 模板字面量
模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。
模板字符串使用反引号 (``) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。
语法:
1 | `string text` |
4.1 多行字符串
在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:
1 | console.log('string text line 1\n' + |
要获得同样效果的多行字符串,只需使用如下代码:
1 | console.log(`string text line 1 |
4.2 字符串插值
普通字符串插入表达式,必须使用如下方式
1 | var a = 5; |
现在通过模板字符串,我们可以使用一种更优雅的方式来表示:
1 | var a = 5; |
4.3 带标签的模板字面量
更高级的是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西 , 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。标签函数并不一定需要返回一个字符串.
1 | function myTag(strings, personExp, ageExp) { |
4.4 原始字符串
在标签函数的第一个参数中,存在一个特殊的属性raw ,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。
1 | function tag(strings) { console.log(strings.raw[0]); } |
另外,使用String.raw() 方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。
1 | var str = String.raw`Hi\n${2+3}!`; |
5. 原有字面量加强
- 更安全的二进制字面量(0b1111101)
- 更安全的八进制字面量(0o767)
- 字符串支持 Unicode
- 正则表达式字面量添加 Unicode 支持(u 标记)
- 正则表达式添加 y 标记,支持粘滞匹配
6. 对象属性加强
- 属性定义支持短语法
obj = { x, y } - 属性名支持表达式
obj = {["baz" + quux() ]: 42} - 添加
__proto__属性,但不建议使用
7. 解构赋值
- 数组匹配
[ b, a ] = [ a, b ] - 对象匹配
let { a, b, c } = objABC - 参数匹配
function g ({ name: n, val: v }) {} - 函数参数默认值
function f({size='big', radius=25} = {}) {}
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
1 | // 解构数组 |
8. 模块
8.1 导出export
在创建JavaScript模块时,export 语句用于从模块中导出函数、对象或原始值,以便其他程序可以通过 import 语句使用它们。无论您是否声明,导出的模块都处于严格模式。 export语句不能用在嵌入式脚本中。
存在两种 exports 导出方式:
- 命名导出(每个模块包含任意数量)
- 默认导出(每个模块包含一个)
1 | // 导出单个特性 |
使用:
1 | // 使用命名导出 |
8.1 导入import
静态的import 语句用于导入由另一个模块导出的绑定。无论是否声明,导入的模块都运行在严格模式下。在浏览器中,import 语句只能在声明了 type="module" 的 script 的标签中使用。
在您希望按照一定的条件或者按需加载模块的时候,动态import() 是非常有用的。而静态型的 import 是初始化加载依赖项的最优选择,使用静态 import 更容易从代码静态分析工具和 tree shaking 中受益。
1 | // 导出文件:/modules/my-module.js文件 |
动态导入import:关键字import可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise。
1 | import('/modules/my-module.js') |
这种使用方式也支持 await 关键字。
1 | let module = await import('/modules/my-module.js'); |
9. 类
10 迭代
11. 生成器Generator
12. Promise
13. 元编程
14. 新增数据类型
15. 原有内置对象 API 增强
- Object.assign
- Array.from
- Array.of
- Array.prototype.fill
- Array.prototype.copyWithin
- Array.prototype.entries
- Array.prototype.keys
- Array.prototype.values
- String.prototype.includes
- String.prototype.repeat
- String.prototype.startsWith
- String.prototype.endsWith
- Number.EPSILON
- Number.isInteger
- Number.isSafeInteger
- Number.isFinite
- Number.isNaN(‘NaN’) // false
- Math.acosh
- Math.hypot
- Math.imul
- Math.sign
- Math.trunc








