Understanding ES6学习笔记
如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
Chapter 4 对象扩展 对象字面量扩展 1.创建对象时,当属性名和变量名相等时,省略属性名 function createPerson(name, age) { return { name, age }; } 2.给对象添加方法时,省略function var person = { name: "Nicholas", sayName() { console.log(this.name); } }; 3.属性名 let lastName = "last name"; let person = { "first name": "Nicholas", [lastName]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person[lastName]); // "Zakas" 用表达式作为属性名: var suffix = " name"; var person = { ["first" + suffix]: "Nicholas", ["last" + suffix]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person["last name"]); // "Zakas" 4.新方法 1.Object.is() 比较两个值是否严格相等 2.Object.assign() 用于对象的合并,将源对象的所有属性复制到目标对象 var target = { a: 1 }; var source1 = { b: 2 }; var source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3} 还可用于为对象添加属性、方法等。 5.重写 "use strict"; var person = { name: "Nicholas", name: "Greg" // no error in ES6 strict mode }; console.log(person.name); // "Greg" 6.属性枚举顺序 Object.getOwnPRopertyNames(obj) 数字按升序排列,字符串按它们添加到对象的顺序排列. 7.改变Prototype Object.setPrototypeOf()方法,接收两个对象最为参数 8.super 指向当前对象原型的指针 原为Object.getPrototypeOf(this).getGreeting.call(this); 改为super.getGreeting(); 【在简化的方法中】,可以通过super调用对象原型上的任何方法。 let friend = { getGreeting: function() { // syntax error return super.getGreeting() + ", hi!"; } };
Chapter 5 解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值。 1.对象解构 let node = { type: "Identifier", name: "foo" }; let { type, name } = node; 变量名和属性名一致 var { foo, bar } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb" 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。 var { foo: baz } = { foo: "aaa", bar: "bbb" }; baz // "aaa" foo // error: foo is not defined 也可嵌套 var obj = { p: [ 'Hello', { y: 'World' } ] }; var { p: [x, { y }] } = obj; x // "Hello" y // "World" 指定默认值 let node = { type: "Identifier", name: "foo" }; let { type, name, value = true } = node; 2.数组解构 数据解构对items的位置操作 模式匹配 let colors = [ "red", "green", "blue" ]; let [ firstColor, secondColor ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green" 交换变量: let a = 1, b = 2; [ a, b ] = [ b, a ]; 3.混合 Chapter 7 1.set: 类似数组,但成员的值唯一 let set=new Set(); 可接收一个数组作为参数,用来初始化。 添加:set.add(value) 判断是否存在:set.has(value) 删除一个:set.delete(value) 删除全部:set.clear() forEach()方法:set.forEach(function(value,key,ownerSet){});forEach方法还可以有第二个参数,表示绑定的this对象。 key和value相等 set里的forEach()不能访问items索引,如需要,则应将其转换为数组。 Array.from方法可将Set结构转换为数组。 set转换为array: array=[...set];(会去除set中的重复项)。 Weak Sets:(对象引用)弱引用 (即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。) WeakSet结构与Set类似,也是不重复的值的集合,但WeakSet的成员只能是对象。 创建: let set=new WeakSet(); 三大集合对象:arrays, maps, sets 2.map:(key-value) let map=new Map(); 添加:map.set(key,value); 检索:map.get(); 对象也可以是key。 也有has(),delete(),clear()方法。 Weak Maps: 每一个key都必须是对象object,键名所指向的对象,不计入垃圾回收机制。 用处:和DOM元素进行数据交互。存储对象实例的专用数据。 (WeakMap的设计目的在于,键名是对象的弱引用(垃圾回收机制不将该引用考虑在内),所以其所对应的对象可能会被自动回收。当对象被回收后,WeakMap自动移除对应的键值对。典型应用是,一个对应DOM元素的WeakMap结构,当某个DOM元素被清除,其所对应的WeakMap记录就会自动被移除。基本上,WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏。) Chapter 8 1.是一个方法,返回一个迭代器。function关键字与函数名之间有一个星号,函数体内部使用yield语句,定义不同的内部状态。 2.function *createIterator(){} let iterator=createIterator(); 指向内部状态的指针对象 如果是匿名函数,星号的位置为: let createIterator=function *(){} 3.yield:执行完一条时,暂停执行,直到下一个next()调用的时候,再执行下一条yield。每次调用next(),返回一个有着value和done两个属性的对象。 4.因为是方法,可添加到对象。 5.for-of 如果只是迭代数组或集合里的值的话用for-of let values=[1,2,3]; for(let num of values){ console.log(num); } 6.通过Symbol.iterator访问默认迭代器 let values=[1,2,3]; let iterator=values[Symbol.iterator](); console.log(iterator.next()); 获取默认迭代器,并用于遍历数组中的items,也是for-of的内部过程。 还可以据此判断一个对象是否可迭代。 7.自定义迭代器 自己创建一个Symbol.iterator属性,该属性包含一个Generator函数。 8.内置迭代器 entries() 返回key-value对 values() 返回values keys() 返回keys 9.三大集合类型的for-of时的默认迭代器 arrays/sets: values() maps: entries() 10.字符串迭代器 for-of 可打印字符串的双字节字符 11. 节点列表迭代器 12.扩展运算符(...) 可将多个数组插入到一个数组中 13.高级迭代器功能 当将参数传递给next()方法时,该参数将成为上一个yield语句的返回值。 iterator.throw(new Error("boom")); 使用yield时,next()和throw()方法控制迭代器中的执行。next()可通过给定值来指示迭代器继续执行,throw()通过抛出错误来指示迭代器继续执行。 14. return 停止执行,done为true,value为undefined。若提供一个返回值,则value为该值,done为true。再执行一条next()时,value变为undefined。 15. 委托 在yield和函数名之间加*号,可以委托给别的Generator。 function *createCombinedIterator(){ yield *createNumberIterator(); yield *createColorIterator(); } 据此可以将多个Generator的value合成一个。 也可访问返回值。 16. 异步编程 因为生成器允许在执行的时候有效地暂停执行,这位异步处理提供了许多可能性。 一个简单的任务运行器,需定义一个函数,接受一个Generator作为参数,在函数内创建一个迭代器并start。 若要传递数据,可将result.value传入next()作为参数。 一个异步的任务运行器,result.value(function(err,data){} 有一个回调函数。 Chapter 9 类 1.类的声明: class PersonClass{ constructor(name){ this.name=name; } sayName(){ console.log(this.name); } } let person=new PersonClass("Jack"); 2.类的声明类似let,存在暂时性死区。 3.在类的里面不能重写类名,在类外可以。 4.类表达式 匿名类表达式,省略类名。let PersonClass=class{} 若有类名,如let PersonClass=class PersonClass2{},则PersonClass2只存在于类内,类外为undefined。 5.ES6中,类可作为函数参数。 6.类表达式可通过立即调用类构造函数来创建实例。需要new。 let person=new Class{ constructor(name){ this.name=name; } sayName(){ console.log(this.name); } }("Jack"); 创建一个匿名类表达式并立即执行。 7.访问器属性 类允许在原型上定义访问器属性。get和set class CustomHTMLElement{ constructor(element){ this.element=element; } get html(){ return this.element.inerHTML; } set html(vlaue){ this.element.innerHTML=vlaue; } } var descriptor=Object.getOwnPropertyDescriptor(CustomHTMLElement.prototype,"html"); console.log("get" in descriptor); //ture 【Object.getOwnPropertyDescriptor(object,propertyname)获取指定对象的自身属性描述符。自身属性描述符是指直接在对象上定义(而非从对象的原型继承)的描述符。】 8.[表达式]使用变量为类定义中的方法分配名称。 let methodName="sayName"; class PersonClass{ constructor(name){ this.name=name; } [methodName](){ cosole.log(this.name); } }; 使用变量为类定义中的方法分配属性名 let propertyName="html"; class CustomHTMLElement{ ... get [propertyName](){...} ... } 9. Generator Methods 定义: class MyClass{ *createIterator(){ yield 1; yield 2; } } let instance=new MyClass(); let iterator=instance.createIterator(); 9.静态成员 class PersonClass{ ... static create(name){ return new PersonClass(name); } } let person=PersonClass.create("Jack"); 10.派生类继承,关键字extends class Rectangle { constructor(length, width) { this.length = length; this.width = width; } getArea() { return this.length * this.width; } } class Square extends Rectangle { constructor(length) { // equivalent of Rectangle.call(this, length, length) super(length, length); } } var square = new Square(3); Square构造函数使用super()来调用具有指定参数的Rectangle构造函数。如果选择不使用构造函数,在创建一个新的类的实例时,super()会被自动调用。 11.继承静态成员 如果基类具有静态成员,那么这些静态成员也可在派生类上使用。 12.表达式派生类 只要表达式带有[[Construct]]的函数和原型,就可以对任何表达式使用extend。在extends之后接受任何类型的表达式提供了强大的可能性,例如动态确定要继承的内容。 chapter 10 数组 1.创建数组 Array.of() 参数为items 2.将一个类数组转换为数组 Array.from() 参数为items,可接收一个函数作为第二个参数,每个item在该函数运行后输出。还可接收第三个参数代表this。 还可在迭代器中使用: let numbers = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; } }; let numbers2 = Array.from(numbers, (value) => value + 1); console.log(numbers2); // 2,3,4 3.find()&findIndex() let numbers = [25, 30, 35, 40, 45]; console.log(numbers.find(n => n > 33)); // 35 console.log(numbers.findIndex(n => n > 33)); // 2 4.fill() 对数组items的整体或部分进行重写 5.copyWithin() 6.Typed Arrays 数组缓存区 所有类型数组的基础是数组缓冲区,它是一个可以包含指定数量字节的内存位置。 创建数组缓冲区:let buffer=new ArrayBuffer(10); console.log(buffer.byteLength); //10 可用slice() 7.使用视图操作数组缓冲区 DataView 数组缓冲区表示内存位置,视图是用于操作该内存的接口。视图对数组缓冲区或数组缓冲区字节的子集进行操作,以一种数值数据类型读取和写入数据。 let buffer=new ArrayBuffer(10); let view=new DataView(buffer); //所有 let view=new DataView(buffer,5,2); //部分 5,6 检索视图信息有三个,buffer,byteOffset,byteLength 8.读写数据 getInt8(byteOffset,littleEndian), setInt8(byteOffset,value,littleEndian 视图允许在任何时间点以任何格式读取和写入,而不考虑之前数据时如何存储的。 9.创建特定类型视图 let buffer=new ArrayBuffer(10), view1=new Int8Array(buffer), view2=new Int8Array(buffer,5,2);