如果区块中存在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);