JavaScript ES6语法知识点

!!本文着重主要是对ES6语法常用知识点的说明,不会讲解一些API层面的语法

1.let/const

ES5只有两种声明变量的方法: var和function

  • var和function命令存在变量提升(var只会先提前声明 function既提前声明又定义)
  • let命令不存在变量提升(const一样)
    JavaScript ES6语法知识点_第1张图片

  • var变量可以重复声明
  • let变量不允许在相同作用域内重复声明(const一样)(通常说一个{}就是一个作用域)
    JavaScript ES6语法知识点_第2张图片

  • var和function命令声明的变量会提升到全局变量window对象中
  • let命令声明的变量在一个叫script作用域下(const一样)
    JavaScript ES6语法知识点_第3张图片

  • 在块级作用域下 var和function声明的变量还是会提升到全局作用域下
  • 在块级作用域下 let声明的变量是私有的(const一样)(在if(){}中的function命令只会声明 条件为true时才会定义)
    JavaScript ES6语法知识点_第4张图片

  • const声明变量的时候必须赋值 ,而且声明的变量不能改变(如果声明的是一个引用类型,则不能改变它的内存地址)

2.解构赋值

  • 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值

  • 数组的解构赋值是按次序排列的;对象的属性没有次序,变量必须与属性同名

  • 解构赋值的变量都会重新声明
    JavaScript ES6语法知识点_第5张图片
    bar是匹配的模式,ba才是变量;真正被赋值的是变量ba ,而不是模式bar
    JavaScript ES6语法知识点_第6张图片
    只有name是变量,a和b都是模式,不会被赋值
    JavaScript ES6语法知识点_第7张图片

  • 解构赋值可以设置默认值
    JavaScript ES6语法知识点_第8张图片
    JavaScript ES6语法知识点_第9张图片

3.模板字符串

  • 用反引号(``)表示;如果嵌入变量需要将变量名写在 ${} 之中

4.函数的扩展

  • 函数的默认参数
    JavaScript ES6语法知识点_第10张图片
    双重默认值:
    在这里插入图片描述

  • rest参数/扩展运算符

rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中(rest 参数之后不能再有其他参数:
在这里插入图片描述

  • 扩展运算符(…)

  • 箭头函数

箭头函数没有arguments;
箭头函数没有prototype属性,没有constructor,即不能用作与构造函数(不能用new关键字调用);
箭头函数没有自己this,它的this是词法的,引用的是上下文的this;
箭头函数不能用作Generator函数

5.对象的扩展

  • 属性和值相同时,可以简写
    在这里插入图片描述

  • 属性名使用[ ],里面可以写变量
    在这里插入图片描述

  • 方法简写
var o = {
 method() {
 return "Hello!";
 }
};
// 等同于
var o = {
 method: function() {
 return "Hello!";
 }
};

  • 对象的取值函数与设值函数
    JavaScript ES6语法知识点_第11张图片

6.Set和WeakSet

  • 去重,Set数据只有value,没有key
    JavaScript ES6语法知识点_第12张图片

  • WeakSet的成员只能是对象,而不能是其他类型的值;而且WeakSet是不可遍历的

    a和b的成员必须要为对象才不会报错
    JavaScript ES6语法知识点_第13张图片

7.Map

  • Map结构和Object结构类似,但是Object结构的“键”的为字符串,Map结构的“键”各种类型
    的值(包括对象)都可以当作键(Object:“字符串—值”;Map:“值—值”)
Map可以接受一个数组作为参数。数组的成员是一个个表示键值对的数组
var map = new Map([
 ['name', '张三'],
 ['title', 'Author']
]);
=====>实际上执行的是下面的算法:
var items = [
 ['name', '张三'],
 ['title', 'Author']
];
var map = new Map();
items.forEach(([key, value]) => map.set(key, value));

  • Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键
var map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined

=========》

var map = new Map();
var k1 = ['a'];
var k2 = ['a'];
map
.set(k1, 111)
.set(k2, 222);
map.get(k1) // 111
map.get(k2) // 222

8.Promise对象

  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject (也是两个函数)
var promise = new Promise(function(resolve, reject) {
 // ... some code
 if (/* 异步操作成功 */){
 resolve(value); //在异步操作成功时回调,并将异步操作的结果,作为参数传递出去
 } else {
 reject(error);//在异步操作失败时回调,并将异步操作报出的错误,作为参数传递出去
 }
});

用then方法分别指定 Resolved 状态和 Reject 状态的两个回调函数:
================================================================>>>
方法1
promise.then(function(value) {
 // success
}, function(error) {
 // failure
});

方法2(推荐)
promise.then(function(value) {
 // success
})
.catch( function(error) {
 // failure
});

JavaScript ES6语法知识点_第14张图片

  • Promise.resolve()/Promise.reject()
如果要将现有对象转为Promise对象

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

===================================================>>
Promise.reject('出错了');
// 等同于
new Promise((resolve, reject) => reject('出错了'))

9.Iterator和for…of循环

  • Iterator(遍历器)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作

模拟 next 方法返回值:
JavaScript ES6语法知识点_第15张图片

  • 对于可遍历的数据结构,ES6在内部部署了一个[Symbol.iterator]属性,它是一个函数,执行后会返回iterator对象(遍历器对象),所以拥有[Symbol.iterator]属性的对象即被视为可遍历的

JavaScript ES6语法知识点_第16张图片

默认具有iterator接口的数据结构有:Array,Map,Set,String,TypedArray(类数组),函数的 arguments 对象,NodeList 对象…

例:
JavaScript ES6语法知识点_第17张图片
变量 arr 是一个数组,原生就具有遍历器接口(部署在 arr的[Symbol.iterator] 属性上面)所以,调用这个属性并执行,就会返回一个iter的遍历器对象

  • 一个数据结构只要部署了 [Symbol.iterator] 属性,就被视为具有iterator接口,就可以用 for…of 循环遍历它的成员。也就是说, for…of 循环内部调用的是数据结构的 Symbol.iterator 方法。

例:for…of 循环本质上就是调用这个接口产生的遍历器对象
JavaScript ES6语法知识点_第18张图片

10.Generator函数

  • Generator 函数是一个状态机,封装了多个内部状态;执行 Generator 函数会返回一个遍历器对象(是一个遍历器对象生成函数)

JavaScript ES6语法知识点_第19张图片
上例生成器函数执行返回一个遍历器对象a,有三个状态:Liu,Jian和Feng;
遍历器对象的 next 方法的运行逻辑:
1.遇到 yield 语句,就暂停执行后面的操作,并将紧跟在 yield 后面的那个表达式的值,作为返回的对象的 value 属性值。
2.下一次调用 next 方法时,再继续往下执行,直到遇到下一个 yield 语句。
3.如果没有再遇到新的 yield 语句,就一直运行到函数结束,直到 return 语句为止,并将 return 语句后面的表达式的值,作为返回的对象的 value 属性值。
4.如果该函数没有 return 语句,则返回的对象的 value 属性值为 undefined 。

  • next方法的参数

yield 句本身没有返回值,或者说总是返回 undefined 。 next 方法可以带一个参数,该参数就会被当作上一个 yield 语句的返回值
JavaScript ES6语法知识点_第20张图片
1.定义了一个可以无限运行的 Generator 函数 f ,如果 next 方法没有参数,每次运行到 yield 语句,变量 reset 的值总是 undefined
2.当 next 方法带一个参数 true 时,变量 reset 就被重置为这个参数(即 true ),因此 i 会等于 -1 ,下一轮循环就会从 -1 开始递增。

JavaScript ES6语法知识点_第21张图片
1.第一次调用 b 的 next 方法时,返回 x+1 的值6;
2.第二次调用 next 方法,将上一次 yield 语句的值设为12,因此 y 等于24,返回 y / 3 的值8
3.第三次调用 next 方法,将上一次 yield 语句的值设为13,因此 z 等于13,这时 x 等于5, y 等于24,所以 return 语句的值等于42
注:由于 next 方法的参数表示上一个 yield 语句的返回值,所以第一次使用 next 方法时,不能带有参数

  • for…of 自动遍历Generator函数时生成的 Iterator 对象(会依次显示yield语句后面的值,不需要使用next方法)
*** yield* 语句在 Generator 函数内部,调用另一个 Generator 函数 ***
function *caoncat(iter1,iter2){
	yield *iter1();
	yield *iter2();
}
等价于
============>
function *caoncat(iter1,iter2){
	for(var value of iter1()){
		yield value;
	}
	for(var value of iter2()){
		yield value;
	}
}

11.async函数

  • async 表示函数里有异步操作, await必须在async函数的上下文中,紧跟在后面的表达式需要等待结果(主要的意图是用来等待 Promise 对象的状态被 resolved,也就是为了异步操作同步化);
  • async 函数的返回值是 Promise 对象,可以使用then方法指定下一步操作(只有 async 函数内部的异步操作全部执行完,除非遇到 return 语句或者抛出错误,才会执行 then 方法指定的回调函数
async function f() {
 await Promise.reject('出错了');
 await Promise.resolve('hello world'); // 不会执行
}

解决办法:把 await 命令放在 try…catch 代码块中

async function f() {
 try {
 await Promise.reject('出错了');
 } catch(e) {
 }
 return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// hello world

  • 多个 await 命令后面的异步操作,如果不存在继发关系,最好让它们同时触发
// 写法一(推荐)
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;


***优秀的例子***
async function dbFuc(db) {
 let docs = [{}, {}, {}];
 let promises = docs.map((doc) => db.post(doc)); // 发送post请求
 let results = [];
 for (let promise of promises) {
 results.push(await promise);
 }
 console.log(results);
}

12.class

参考实现继承的多种方式

13.Module

参考模块规范之ES6,CommonJS,AMD,CMD

总结:上述都为个人见解以及对ES6书籍部分的摘抄,如有不正,欢迎指正

你可能感兴趣的:(JS)