ECMAScript 6入门学习笔记

一、变量
  1. let:let所声明的变量只在所处的块级作用域有效
    (1) 具有块级作用域
    (2) 不存在变量提升
    (3) 具有暂时性死区特性:即在变量声明之前的引用都会报错
    (4) 不允许重复声明
  2. const常量:
    (1) 具有块级作用域
    (2) 声明时必须赋值
    (3) 赋值之后无法被修改,但复杂数据类型可修改内部的成员(复杂数据类型实际指向的是地址)
  3. 三者区别:
    (1) var存在变量提升,作用域为该语句所在的函数
    (2) let、const不存在变量提升,且只在所处的块级作用域有效,另外const必须在声明时赋值。
    (3) let、const、class命令声明的全局变量不属于全局对象的属性。
  4. 块级作用域:
    (1) 防止内层变量覆盖外层变量
    (2) 防止循环变量泄漏变成全局变量
    (3) 可以代替匿名函数
  5. 跨模块常量:export const A = 1; import { A } from './constants';
二、 解构赋值
  1. ES6中允许从数组内提取值,但需按照对应的位置对变量进行赋值。其中对象也可以进行解构。
  2. 数组解构:let [a,b,c] = [1,2,3]; let [a,b] = [1]; //此时解构不成功,b为undefined
  3. 对象解构:let {b,a:value} = {a:‘1’,b:2}; let Person = {a:1}; let {a} = Person; 无次序,但变量名需一致。
  4. 函数字面量增强写法:let obj = {run: function(){}} 可写成 let obj = { run(){} }
三、字符串扩展
  1. forEach、for…in、for…of区别:forEach无法使用return、continue、break终止循环,for…in遍历的是键名,for…of遍历的是键值。
  2. 新增查找字符串方法:includes(是否包含该字符串),startsWith(是否在源字符串头部),endsWith(是否在源字符串尾部),方法中的第二个参数表示从第n个到最后一个字符开始搜索(也就是第n个字符才是搜索的第一个字符),而endsWith比较特殊,表示前n个字符。
  3. repeat方法表示将原字符重复n次,返回新的字符串。'x'.repeat(3); //xxx
  4. padEnd、padStart方法接受两个参数,第一个指定字符串的长度,第二个是补全字符串的字符。'x'.padEnd(5,ab) //xabab
  5. 模板字符串:可识别换行符,需要使用反引号,若模板需要使用反引号则用反斜杠来转义。模板字符串中可引用变量,如:
    ECMAScript 6入门学习笔记_第1张图片
四、数组扩展
  1. Array.from()方法可以将伪数组转换为真数组(伪数组的索引实际为键名,与真数组相比缺少数组的方法,且可能没有length属性,如函数的arguments对象,dom操作获取的对象集合)。let arr = Array.from(arrayLike);
  2. Array.of()方法可以将一组值转换为一个数组。
  3. find、findIndex方法接受一个回调函数参数,回调函数参数有三个:value、index、arr。
  4. keys、values、entries方法都返回一个迭代器对象,分别返回键名、键值、键值对。
  5. includes方法查询数组是否包含该值
五、函数扩展
  1. 函数参数默认值:function fn(x=200){}
  2. 函数length属性:指定默认值之后函数的length属性将返回没有指定默认值的参数个数
  3. 剩余参数 function sum(a,b,...args) { console.log(...args) }; sum(10,20,30,40); //30 40,而args为一个数组,打印时也将该数组展开了。需要注意的是剩余参数rest只能是最后一个参数。
  4. 扩展运算符
    1. 利用扩展运算符将两个数组合并:let arr = […arr1,…arr2];
    2. 扩展运算符和解构赋值配合使用:let [s1,…s2] = [1,2,3]; s1为1,s2为一个数组,其中s2[0]为2,s2[1]为3
    3. 利用扩展运算符合并对象:let obj = {...obj1,age:18};
    4. ES5将数组转为为参数传入函数:fn.apply(null,args);ES6可利用剩余参数:fn(…args);
    5. 通过push函数将一个数组添加到另一个数组尾部:Array.prototype.push.apply(arr1,arr2); 通过剩余参数可写成:arr1.push(…arr2);
    6. 另外可以将伪数组转换为真正的数组:arr = […nodeList];
    7. 将字符串转为数组
  5. name方法返回函数名
  6. 箭头函数:
    1. 语法:() => {}
    2. 如果有且仅有一个参数,则可以省略()
    3. 如果执行语句只有一句且为return,则可以省略{}, res => res+5;
    4. 箭头函数没有this指向,当使用this时会在定义时的上下文查找this作为自己的this值。而普通的函数this取决于调用者。
    5. 当箭头函数作为对象的方法时,由于对象不产生作用域,所以其this指向的是window。
    6. 另补充普通函数的this指向问题:
      (1)普通函数:window
      (2)对象方法:指向对象
      (3)构造函数:指向实例对象,new 创建对象 this是永远指向实例对象的 即使没赋予变量名 也不会指向 window 只有直接调用构造函数时,this才指向window
      (4)btn.onclick = function() {}; 指向按钮
      (5)定时器函数:指向window
      (6) 立即调用函数:指向window
    7. 箭头函数与解构赋值搭配使用:const full = ({first,last}) => first + ' ' last;
  7. 尾调用,在函数最后返回的是一个调用的函数。此时可以只保留最后一个调用帧。
  8. 尾递归:利用尾调用,如阶乘递归,将需要累积的变量写入函数参数,此时只存在一个调用帧,不会发生栈溢出。
六、对象扩展
  1. 属性的简写:var baz = {foo} 等同于 var baz = {foo:foo}
  2. 方法简写:say: function(){} 可以简写为 say() {}
  3. 对象新增方法…
七、新增类型Symbol
  1. 语法:let s = symbol(); symbol函数前不能使用new命令,可接受一个字符串作为参数,表示对symbol实例的描述。
  2. 特点:凡是属性名属于Symbol类型的都是独一无二的,相同参数的Symbol函数的返回值也是不相等的。
  3. 作为属性名的用法:
    1. var mySymbol = Symbola('mySymbol'); var a = {}; a[mySymbol] = 'Hello!';
    2. var mySymbol = Symbola('mySymbol'); var a = {[mySymbol]: 'Hello!' };
    3. var mySymbol = Symbola('mySymbol'); var a = {}; Object.defineProperty(a,mySymbol,{value: 'Hello!'})
  4. Symbol作为对象属性名不能用点运算符。
  5. Symbol作为对象属性名不能被for…of,for…in循环遍历,只能使用getOwnPropertySymbols方法获取。
  6. 重新使用同一个Symbol值:Symbol.for()方法接受一个字符串作为参数,会先搜索全局是否有以这个参数作为名称的Symbol值,若有则返回整个Symbol值,若无则新建一个Symbol值。同时会在全局环境中登记该Symbol值。
  7. Symbol.keyFor()与Symbol.for()方法相似,返回的是Symbol类型值的key,但搜索不到时返回undefined(该方法无法搜索到未登记的Symbol值)。
  8. 应用场景:同一个班级出现相同名字的同学,此时数据无法重复定义在对象内。可利用Symbol来定义
	let student1 = {name: 'John'',key: Symbol()};
	let student2 = {name: 'John'',key: Symbol()};
	let grade = {
		[student1.key] : {math: 100}
		[student2.key] : {math: 99}
	}
八、Set和Map数据结构
  1. Set数据结构(集合)里的项不会有重复的值。(5和"5"视为不同值,但NAN视为同一个值)
  2. Set内的方法和属性:
    1. size属性:返回Set实例的成员总数
    2. add(value)方法:向实例内添加一项,但不会添加重复的项,返回Set实例
    3. delete(value)方法:删除集合内的某一项,返回布尔值表示是否删除成功
    4. has(value)方法:查询集合内是否包含该值,返回布尔值
    5. clear方法:清除所有成员,不返回任何值
  3. Array.from可以将Set结构转换为数组,可以利用该方法进行数组去重:Array.from(new Set([1,1,2,3,4]));
  4. 遍历Set实例:keys、values、entries(获取值,返回数组再利用for…of来进行遍历)或直接利用forEach遍历
  5. 利用展开运算符进行数组去重:console.log(...new Set([1,1,2,3,4]))
  6. 利用filter方法实现并集、交集、差集:
    ECMAScript 6入门学习笔记_第2张图片
  7. WeakSet:WeakSet结构与Set类似,区别如下:
    1. WeakSet结构的成员只能是对象
    2. WeakSet结构内的对象都是弱引用,垃圾回收机制不会考虑该结构对该对象的引用直接回收,因此该结构哦无法进行遍历
    3. 方法:has(),add(),delete()
    4. 应用场景:存储dom节点,此时不用担心节点从文档移除时发生内存泄漏
  8. Map结构(映射):该数据结构类似对象,但对象中的键只能是字符串,而Map中键的范围不限于字符串
  9. 语法:
    在这里插入图片描述
  10. map结构中可设置对象为键,但需要同一个引用才视为同一个键。(但NAN在该数据结构中视为同一个键)
  11. Map结构的属性和方法:
    1. size属性:返回实例成员总数
    2. set方法:设置实例中key所对应的键值,返回整个实例,若已存在该key则更新原来的值
    3. get方法:读取实例中key所对应的键值
    4. has方法:查询某个键,返回布尔值
    5. delete方法:删除某个键,返回布尔值
    6. clear方法:清除所有成员,无返回值
  12. 遍历Map实例:keys、values、entries(获取值,返回数组再利用for…of来进行遍历)或直接利用forEach遍历
  13. 将Map结构转换为数组:[…m.keys()]
  14. 在Map中使用map和filter方法:
    在这里插入图片描述
  15. WeakMap:与Map结构类似,但只接受对象作为键名(null除外),并且键名对于对象是弱引用(垃圾回收机制不会将其考虑在内)
  16. WeakMap方法:get、set、has、delete
九、Iterator遍历器
  1. Iterator是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署了Iterator就可以完成遍历操作。
  2. JS的四种数据结构:数组、对象、Map、Set中除了对象都有默认的遍历器,Iterator接口主要供for…of消费。其中字符串是一个类似数组的对象,也具有原生的Iterator接口。
十、异步操作(Generator)
  1. 语法:function* fn(){yield};
  2. Generator中的yield关键字可以将函数暂停执行,可以看作是将一个函数分隔成几个小函数,此时yield右侧的值即该次调用返回的结果,而左侧可以使用一个变量来接受yield,此时可以通过next()来传参。
  3. 调用Generator函数时并不会执行该函数,而是会返回一个Generator对象,此时再调用该对象的方法时会执行函数至下一个yield关键字为止。
  4. 在Generator函数最后可以使用return来返回最终的执行结果。
  5. 在Generator函数中调用另一个函数可以使用yield语句。
十一、异步操作(promise)
  1. Promise:
new Promise(function (resolve,reject) {
			$.ajax({url:'data/1.txt',    //语法
			dataType:'json',
			success(data) {
				resolve(data);						//若Promise对象resolve另外一个Promise对象,则另一个Promise对象的状态会传递给这个对象,也就是这个对象实际的状态取决于返回的那个Promise对象
			},
			error(err) {
				reject(err);						//若Promise对象reject另一个对象,则仍然是直接失败调用reject函数,但还是会执行另一个Promise对象
			}
		})
		}).then(function(data) {},function (err) {});
  1. Promise.all方法
Promise.all([
$.ajax({url:'data/1.txt', dataType:'json'}),	
$.ajax({url:'data/1.txt', dataType:'json'}),
$.ajax({url:'data/1.txt', dataType:'json'})])
.then(([data1,data2,data3]) => {						  //有一个请求失败则失败
	console.log(data1,data2,data3);
}, err => {
	console.log(err);
})
  1. Promise说明:

    1. promise有三个状态,pedding(初始状态),fulfilled(成功状态),rejected(失败状态)。
    2. promise可通过 .then 实现链式调用,其中 .then 接收两个函数作为参数(分别代表fulfilled和rejected),而两个函数中各有一个参数(成功和失败返回的参数)。
    3. 状态响应函数中可以返回新的promise或者其他值,无返回值则为null。若返回是其他值则将会作为下一个then方法拿到的参数,如果返回的值是新的promise对象则参数拿到的值为promise resolve()传递的值。
    4. 当返回新的promise时,下一个.then会等待返回的promise状态改变再判断执行哪一个函数。
    5. 若为其他值则立即执行下一个.then。
  2. Promise捕获错误:
    (1)使用throw抛出异常,通过catch捕获错误。(推荐做法)
    ECMAScript 6入门学习笔记_第3张图片
    (2)使用reject捕获错误:
    ECMAScript 6入门学习笔记_第4张图片

  3. 使用Promise连续发送有依赖关系的请求:
    ECMAScript 6入门学习笔记_第5张图片

十二、异步操作(async/await)
  1. async/await:await后面接一个返回Promise对象的函数并执行它,且await只能放在async函数里。
  2. async函数会返回一个Promise对象,可在then方法后面添加回调函数。
  3. await:当执行async函数内部语句遇到await语句时,会暂时阻塞后面语句的执行,之后先执行async函数外面的同步代码,再返回async内部继续执行。如果await等待的不是Promise对象,则直接作为表达式结果,继续执行下面的代码。若是Promise对象则等待该Promise对象resolve,之后将resolve返回的结果返回。(若返回的是Promise对象,但没有resolve结果,则await拿不到值,执行失败)
  4. try{ 正常执行的操作 }catch(e){ 捕获到失败执行的操作 }

你可能感兴趣的:(JavaScript)