ECMAScript 6 新特性详解(上)

简介: ECMAScript 6 新特性详解(上)

ECMAScript 6 简介

ECMAScript 6,也称为ECMAScript2015,是ECMAScript标准的最新版本。ES6是该语言的一次重大更新,也是自2009年ES5标准化以来该语言的首次更新。目前正在主要的JavaScript引擎中实现这些功能。

有关ECMAScript 6语言的完整规范,请参阅ES6标准。

https://262.ecma-international.org/6.0/

ES6包括以下新功能:

  • 箭头函数
  • 增强对象字面量
  • 模板字符串
  • 解构赋值
  • 默认参数、剩余参数、展开操作符
  • let、const
  • Iterators(迭代器)、for of
  • Generators(生成器)
  • unicode
  • 模块
  • 模块加载器(提案,未正式成为ES6的一部分)
  • map、set、weakmap、weaakset
  • Proxy
  • Symbol
  • 继承
  • Promise
  • Math + Number + String + Array + Object APIs
  • 二进制,八进制
  • Reflect API
  • 尾递归

1、箭头函数

箭头是使用=>语法的函数简写。与函数不同,箭头与其周围的代码共享相同的词法this。

1. let age = [20, 22, 24, 26].map(res=>res+1)  // [21, 23, 25, 27]
2. 
3. // 词法 this
4. var people = {
5. name: 'zhangsan',  
6.  age: 23,
7. course: ['语文', '数学', '英语'],
8.   getCourse () {
9. this.course.forEach(res =>
10. console.log(this.name + ' 课程 ' + res)
11.     );
12.   }
13. }
14. people.getCourse()  
15. //  zhangsan 课程 语文
16. //  zhangsan 课程 数学
17. //  zhangsan 课程 英语
18. 
19. // 然后我们把getCourse()方法改一下
20. this.course.forEach(function(res) {
21. console.log(this.name + ' 课程 ' + res)
22. });
23. //            课程 语文 
24. //            课程 数学
25. //            课程 数学
26. // this.name 没有获取到,这时this指向windows对象

2、类

在ES6中,类是基于原型的面向对象的简单补充,类支持基于类型的继承,父级super调用,实例,静态方法,构造函数

1. class animal {
2. constructor(age) {
3. this.walk = '走';
4.   }
5. }
6. class monkey extends animal {
7.   constructor(age, name) {
8. super(age); // 调用父类的constructor(age)
9. this.age = 12;
10.   }
11. static defaultColor() {
12.     rerun 'white'
13.   }
14. }
15. let mon = new monkey(33)  // 进行实例化
16. console.log(mon)   // {walk: '走', age: 33}
17. monkey.defaultColor()  // 'white' 这里静态方法可以直接调用,不需要实例化

3、增强对象字面量

1. var faObj = {
2.   get Pname () {return '父对象'},
3.   toString () {
4. return 'String'
5.   }
6. }
7. var handler = function () {return 'handler'}
8. var obj = {
9. // __proto__
10. __proto__: faObj,
11. // 简短写法 ‘handler: handler’
12.   handler,
13. // 定义当前对象的toString() 方法
14. toString() {
15. // 调用父对象toString()方法
16. return "d " + super.toString();
17.   },
18. // 字面量值会进行自动计算 prop_111: 111
19.   [ 'prop_' + (() => 111)() ]: 111
20. };
21. console.log(obj) 
22. // {handler: f(), prop_111: 111, toString: toString(), Pname: ()}

4、模板字符串

模板字面量是用反引号(`)分隔的字面量,允许多行字符串、带嵌入表达式的字符串插值和一种叫带标签的模板的特殊结构。

1. // 多行字符串
2. console.log('string text line 1\n' + 'string text line 2');
3. // "string text line 1
4. // string text line 2"
5. 
6. // 嵌入表达式的字符串插值
7. var name = "zhangsan", age = 23;
8. console.log(`Hello ${name}, age ${age}?`)
9. // 'Hello zhangsan, age 23?'
10. 
11. // 带标签的模板
12. var age = 23, sex = '男'
13. function tag (string, exp1, exp2) {
14. return `hello ${string} ${exp1} ${exp2}`
15. }
16. tag`zhangsan ${age} ${sex}`
17. // 'hello zhangsan , , 23 男'

5、解构赋值

解构赋值语法是一种 Javascript 表达式。可以将数组中的值或对象的属性取出,赋值给其他变量。

1. var [a,b,c] = [1,2,3]  // 数组赋值,进行匹配
2. const obj = { a: 1, b: 2 };
3. const { a, b } = obj;  // 对象解构
4. const foo = ['one', 'two', 'three'];
5. const [red, yellow, green] = foo; // 数组解构
6. // 剩余解构
7. const { a, ...others } = { a: 1, b: 2, c: 3 };
8. console.log(others); // { b: 2, c: 3 }
9. 
10. const [first, ...others2] = [1, 2, 3];
11. console.log(others2); // [2, 3]
12. // 变量置换
13. let a = 1,b = 2;
14. [a, b] = [b, a];

6、默认参数、剩余参数、展开操作符

1. function f(x, y=1) { // y 默认为1,如果传参,则覆盖默认值
2. return x + y;
3. }
4. f(1) == 2     // true
5. f(1, 2) == 3  // true
6. 
7. function f(x, ...y) {
8. // y 是一个数据组
9. return x * y.length;
10. }
11. f(2, "hello", true, 123) == 6
12. 
13. function f(x, y, z) {
14. return x + y + z;
15. }
16. // 将数组的每个元素作为参数传递
17. f(...[1,2,3]) == 6

7、let、const

let 语句声明一个块级作用域的局部变量,并可以初始化为一个值(可选)。

let 声明的变量作用域只在其声明的块或子块内部,这一点,与 var 相似。二者之间最主要的区别在于 var 声明的变量的作用域是整个封闭函数。

1. function varTest() {
2.  var x = 1;
3.   {
4. var x = 2; // 相同
5. console.log(x); // 2
6.   }
7.  console.log(x); // 2
8. }
9. function letTest() {
10. let x = 1;
11.   {
12. let x = 2; // 不同
13. console.log(x); // 2
14.   }
15. console.log(x); // 1
16. }

var 声明的变量会在整个封闭函数内有影响,而let之只在区块内有影响。

在全局作用域中,let 和 var 不一样,它不会在全局对象上创建属性。

1. var x = 'global';
2. let y = 'global';
3. console.log(this.x); // "global"
4. console.log(this.y); // undefined

在同一个函数或块作用域中重复声明同一个变量会抛出 SyntaxError。

1. if (x) {
2. let foo;
3. let foo; // SyntaxError thrown.
4. }

从一个代码块的开始直到代码执行到声明变量的行之前,let 或 const 声明的变量都处于“暂时性死区”(Temporal dead zone,TDZ)中。

1. { // TDZ starts at beginning of scope
2. console.log(bar); // undefined
3. console.log(foo); // ReferenceError
4. var bar = 1;
5. let foo = 2; // End of TDZ (for foo)
6. }

const 基本用法

常量是块级范围的,非常类似用 let 语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。

常量在声明的时候可以使用大小写,但通常情况下全部用大写字母。

1. cont MY_AGE = 20;  
2. MY_AGE = 20;  // caught TypeError: Assignment to constant variable.
3. const MY_AGE = 20;  // 尝试重新声明会报错
4. const NAAME; // Uncaught SyntaxError: Missing initializer in const declaration

常量可以定义成对象和数组

1. const MY_OBJECT = {'key': 'value'};
2. const MY_ARRAY = []

const 声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。

8、迭代器(迭代器)、for of

for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

1. const array1 = ['a', 'b', 'c'];
2. for (const element of array1) {
3.  console.log(element);
4. }
5. // a 
6. // b
7. // c

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式,当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

1. function* fibonacci() { // 一个生成器函数
2. let [prev, curr] = [0, 1];
3. for (;;) { // while (true) {
4.     [prev, curr] = [curr, prev + curr];
5. yield curr;
6.   }
7. }
8. for (let n of fibonacci()) {
9. console.log(n);
10. // 当 n 大于 1000 时跳出循环
11. if (n >= 1000)
12.     break;
13. }

迭代基于这些鸭子类型的接口(仅使用TypeScript类型语法进行说明):

1. interface IteratorResult { // 迭代器返回结果接口
2. done: boolean;
3. value: any;
4. }
5. interface Iterator {    // 迭代器接口
6. next(): IteratorResult;
7. }
8. interface Iterable {  // 可迭代接口
9.   [Symbol.iterator](): Iterator
10. }

9、Generators(生成器)

生成器使用函数*和yield简化迭代器的编写。声明为函数*的函数返回一个Generator实例。生成器是迭代器的子类型,其中包括额外的next和throw。这些使值能够返回到生成器,因此yield是一种返回值(或抛出)的表达式形式。

Generator 构造函数并不是全局可用。Generator 的实例必须从生成器函数返回:

1. function* generator() {
2. yield 1;
3. yield 2;
4. yield 3;
5. }
6. const gen = generator(); // "Generator { }"
7. console.log(gen.next().value); // 1
8. console.log(gen.next().value); // 2
9. console.log(gen.next().value); // 3


相关文章
|
3月前
|
自然语言处理 JavaScript 前端开发
ECMAScript 2022 正式发布,有哪些新特性?(下)
ECMAScript 2022 正式发布,有哪些新特性?(下)
|
3月前
|
存储 JavaScript 前端开发
ECMAScript 2022 正式发布,有哪些新特性?(上)
ECMAScript 2022 正式发布,有哪些新特性?(上)
|
3月前
|
JavaScript 前端开发 Unix
ECMAScript 2023 正式发布,有哪些新特性?
ECMAScript 2023 正式发布,有哪些新特性?
|
7月前
|
JavaScript 前端开发 索引
ECMA 2022 (es13) 新特性
ECMA 2022 (es13) 新特性
36 0
|
7月前
|
存储 JavaScript 前端开发
ECMAScript 2020(ES11)新特性简介
ECMAScript 2020(ES11)新特性简介
63 0
|
10月前
|
存储 前端开发 JavaScript
ECMAScript 6 新特性详解(下)
ECMAScript 6 新特性详解(下)
|
10月前
|
存储 JSON JavaScript
ECMAScript 6 新特性详解(中)
ECMAScript 6 新特性详解(中)
|
JSON JavaScript 前端开发
ECMAScript6.0基础
1.什么是ES6 ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 标准的制定者有计划,以后每年发布一次标准,使用年份作为版本。因为ES6的第一个版本是在2015年发布的,所以又称ECMAScript 2015(简称ES2015)。
236 0
ECMAScript6.0基础
|
JavaScript 前端开发
ECMAScript 6新特性简介
ECMAScript 6新特性简介
ECMAScript 6新特性简介
|
JavaScript 前端开发 Java
ECMAScript 2018(ES9)新特性简介
ECMAScript 2018(ES9)新特性简介