let和const
- let在塊級作用域有效。不存在之前的var的作用域提升。
- const意思是隻讀的變量。不可以在聲明之後再改變值。
- const指向對象的時候,對象可以改變屬性,但是對象不能變。
{
let a=1;
}
for(let i=0;i<10;i++){
}
變量的解構
1.數組的解構。
- 左邊的變量對等於右邊的值。
- 值的長度可變,不存在則等於undefined
- 右邊的結構要求實現Iterator ,數組、Set都算。
- -可以在定義之前指定默認值,如果右邊不存在則使用默認值,(null也算賦值)
let [a, b, c] = [1, 2, 3];
let [x, y, z] = new Set(['a', 'b', 'c']);
let [foo = true] = [];
2.對象的解構
- 變量名等於屬性名對應的值
- 可以指定對象名對應的值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
3.字符串也可以解構
const [a, b, c, d, e] = 'hello';
let {length : len} = 'hello';
4.函數參數的解構
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
5.解構的表達式中不能使用圓括號’()’,一旦使用就會報錯
字符串新方法
- “\u{41}\u{42}\u{43}”表示法
- codePointAt獲取字符串的十進制
- fromCodePoint從進制轉字符串
- for…of接口
- at返回下標對應的字符
- normalize
- includes、startsWith、endsWith
- repeat
- padStart、padEnd補全
- 模板字符串
aaa${name}
- 標籤模板
- String.raw
Hi\n${2+3}!
以上做一個備註
正則的擴展
- new RegExp(/abc/ig, ‘i’)
- String.prototype.match調用RegExp.prototype[Symbol.match]
- u修飾符
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0;
//返回中文字符串的正確長度
- y修飾符
- sticky
- flags
- s修飾符
數值擴展
- 0b二進制和0o八進制表示法
- Number.isFinite()和Number.isNaN()
- Number.parseInt(), Number.parseFloat()
- Number.isInteger()是否爲整數
- Number.EPSILON常量
- Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER上下限
- Math.trunc()去掉小數部分
- Math.sign()正負數判斷
- Math.cbrt() 計算立方根
- Math.clz32()
- Math.imul()
- Math.fround()
- Math.hypot()
- Math.expm1()
- Math.log1p()
- Math.log10()
- Math.log2()
- 指數運算符**
函數的擴展
- 函數參數默認值,默認值在最後
- length返回沒有默認值的參數個數
- rest 參數(形式爲…變量名)
- name返回函數名稱
- 箭頭函數。
var f = () => 5;
// 等同於
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2) {
return num1 + num2;
};
1.函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
2.不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。
3.不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。
4.不可以使用yield命令,因此箭頭函數不能用作 Generator 函數。
- ::綁定 this
- 尾調用,優化
數組的擴展
- 擴展運算符…
- Array.from將類似數組(包含length屬性)和實現了Iterable的對象轉爲數組。第二個參數是處理方法
- Array.of()將參數轉爲數組
- copyWithin(開始位置,開始讀取位置,結束讀取位置)
- find,findIndex
- fill(填充值,開始位置,結束位置)
- entries(),keys() 和 values()
- includes(是否包含的值,開始查詢的位置)
屬性的擴展
- 屬性的簡潔表示法
- 字面量定義對象,不能同時使用簡潔表示法
let propKey = 'foo';
let obj = {
[propKey]: true,
['a' + 'bc']: 123
};
- 方法的 name 屬性
- Object.is()
Object.assign()
1.for…in循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
2.Object.keys返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含 Symbol 屬性)
3.Object.getOwnPropertyNames返回一個數組,包含對象自身的所有屬性(不含 Symbol 屬性,但是包括不可枚舉屬性)。
4.Object.getOwnPropertySymbols返回一個數組,包含對象自身的所有 Symbol 屬性。
5.Reflect.ownKeys返回一個數組,包含對象自身的所有屬性,不管屬性名是 Symbol 或字符串,也不管是否可枚舉。Object.getOwnPropertyDescriptors()
- Object.create
- Object.setPrototypeOf()和Object.getPrototypeOf()
- Object.keys(),Object.values(),Object.entries()
- 對象的擴展運算符…
Symbol
ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。
let s = Symbol();
typeof s
// "symbol"
var mySymbol = Symbol();
// 第一種寫法
var a = {};
a[mySymbol] = 'Hello!';
// 第二種寫法
var a = {
[mySymbol]: 'Hello!'
};
// 第三種寫法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"
- Object.getOwnPropertySymbols可以獲取到對象的Symbol屬性
- Symbol.for(),Symbol.keyFor()
Set和Map
Set
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 2 3 5 4
- Set.prototype.constructor:構造函數,默認就是Set函數。
- Set.prototype.size:返回Set實例的成員總數。
- add(value):添加某個值,返回Set結構本身。
- delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
- has(value):返回一個布爾值,表示該值是否爲Set的成員。
- clear():清除所有成員,沒有返回值。
- keys():返回鍵名的遍歷器
- values():返回鍵值的遍歷器
- entries():返回鍵值對的遍歷器
- forEach():使用回調函數遍歷每個成員
WeakSet
1.WeakSet 的成員只能是對象,而不能是其他類型的值。
2.WeakSet 中的對象都是弱引用,即垃圾回收機制不考慮 WeakSet 對該對象的引用
Map
const map = new Map([
['name', '張三'],
['title', 'Author']
]);
map.size // 2
map.has('name') // true
map.get('name') // "張三"
map.has('title') // true
map.get('title') // "Author"
- keys():返回鍵名的遍歷器。
- values():返回鍵值的遍歷器。
- entries():返回所有成員的遍歷器。
- forEach():遍歷 Map 的所有成員。
WeakMap
1.WeakMap只接受對象作爲鍵名(null除外),不接受其他類型的值作爲鍵名。
2.WeakMap的鍵名所指向的對象,不計入垃圾回收機制。
WeakMap 與 Map 在 API 上的區別主要是兩個,一是沒有遍歷操作(即沒有key()、values()和entries()方法),也沒有size屬性。因爲沒有辦法列出所有鍵名,某個鍵名是否存在完全不可預測,跟垃圾回收機制是否運行相關。這一刻可以取到鍵名,下一刻垃圾回收機制突然運行了,這個鍵名就沒了,爲了防止出現不確定性,就統一規定不能取到鍵名。二是無法清空,即不支持clear方法。因此,WeakMap只有四個方法可用:get()、set()、has()、delete()。
Proxy
1.get(target, propKey, receiver)
2.set(target, propKey, value, receiver)
3.has(target, propKey)
4.deleteProperty(target, propKey)。用於攔截delete操作
5.ownKeys(target)
6.getOwnPropertyDescriptor(target, propKey)
7.defineProperty(target, propKey, propDesc)。攔截了Object.defineProperty操作
8.preventExtensions(target)
9.getPrototypeOf(target)
10.isExtensible(target)
11.setPrototypeOf(target, proto)
12.apply(target, object, args)
13.construct(target, args)。方法用於攔截new命令
Reflect
1.將Object對象的一些明顯屬於語言內部的方法(比如Object.defineProperty),放到Reflect對象上。現階段,某些方法同時在Object和Reflect對象上部署,未來的新方法將只部署在Reflect對象上。也就是說,從Reflect對象上可以拿到語言內部的方法。
2.修改某些Object方法的返回結果,讓其變得更合理。比如,Object.defineProperty(obj, name, desc)在無法定義屬性時,會拋出一個錯誤,而Reflect.defineProperty(obj, name, desc)則會返回false。
- Reflect.apply(target,thisArg,args)
- Reflect.construct(target,args)
- Reflect.get(target,name,receiver)
- Reflect.set(target,name,value,receiver)
- Reflect.defineProperty(target,name,desc)
- Reflect.deleteProperty(target,name)
- Reflect.has(target,name)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, name)
- Reflect.getPrototypeOf(target)
- Reflect.setPrototypeOf(target, prototype)
Promise
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
Iterator(遍歷器)
1.創建一個指針對象,指向當前數據結構的起始位置。也就是說,遍歷器對象本質上,就是一個指針對象。
2.第一次調用指針對象的next方法,可以將指針指向數據結構的第一個成員。
3.第二次調用指針對象的next方法,指針就指向數據結構的第二個成員。
4.不斷調用指針對象的next方法,直到它指向數據結構的結束位置。
const obj = {
[Symbol.iterator] : function () {
return {
next: function () {
return {
value: 1,
done: true
};
}
};
}
};
Generator
Generator 函數有多種理解角度。從語法上,首先可以把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。
執行 Generator 函數會返回一個遍歷器對象,也就是說,Generator 函數除了狀態機,還是一個遍歷器對象生成函數。返回的遍歷器對象,可以依次遍歷 Generator 函數內部的每一個狀態。
形式上,Generator 函數是一個普通函數,但是有兩個特徵。一是,function關鍵字與函數名之間有一個星號;二是,函數體內部使用yield表達式,定義不同的內部狀態(yield在英語裏的意思就是“產出”)。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
yield 表達式
(1)遇到yield表達式,就暫停執行後面的操作,並將緊跟在yield後面的那個表達式的值,作爲返回的對象的value屬性值。
(2)下一次調用next方法時,再繼續往下執行,直到遇到下一個yield表達式。
(3)如果沒有再遇到新的yield表達式,就一直運行到函數結束,直到return語句爲止,並將return語句後面的表達式的值,作爲返回的對象的value屬性值。
(4)如果該函數沒有return語句,則返回的對象的value屬性值爲undefined。
需要注意的是,yield表達式後面的表達式,只有當調用next方法、內部指針指向該語句時纔會執行,因此等於爲 JavaScript 提供了手動的“惰性求值”(Lazy Evaluation)的語法功能。
async
var fs = require('fs');
var readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
};
var gen = function* () {
var f1 = yield readFile('/etc/fstab');
var f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
//等同於
var asyncReadFile = async function () {
var f1 = await readFile('/etc/fstab');
var f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
Class
//定義類
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
static classMethod() {
return 'hello';
}
}
//繼承
class Point {
}
class ColorPoint extends Point {
}
類的修飾
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
Module 的語法
import { stat, exists, readFile } from 'fs';
ES6 的模塊自動採用嚴格模式,不管你有沒有在模塊頭部加上”use strict”;。
嚴格模式主要有以下限制。
- 變量必須聲明後再使用
- 函數的參數不能有同名屬性,否則報錯
- 不能使用with語句
- 不能對只讀屬性賦值,否則報錯
- 不能使用前綴0表示八進制數,否則報錯
- 不能刪除不可刪除的屬性,否則報錯
- 不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
- eval不會在它的外層作用域引入變量
- eval和arguments不能被重新賦值
- arguments不會自動反映函數參數的變化
- 不能使用arguments.callee
- 不能使用arguments.caller
- 禁止this指向全局對象
- 不能使用fn.caller和fn.arguments獲取函數調用的堆棧
- 增加了保留字(比如protected、static和interface)
上面這些限制,模塊都必須遵守。由於嚴格模式是 ES5 引入的,不屬於 ES6,所以請參閱相關 ES5 書籍
其中,尤其需要注意this的限制。ES6 模塊之中,頂層的this指向undefined,即不應該在頂層代碼使用this。