let和const
-
let
:聲明變量榜旦,只在let所在作用域內有效,在聲明變量之前澡屡,該變量都不能使用驶鹉,被稱為暫時性死區(qū)铣墨。 -
let
和const
沒有變量提升 -
let
不允許在相同的作用域內重復聲明同一個變量 -
const
:聲明的值不得改變,const
一旦聲明變量就必須立即初始化孕蝉,不能留到以后賦值const
:實質是保證變量指向的內存地址所保存的數據不能改動肉盹。 - 頂層對象上忍,瀏覽器中指
window
,node中指global
模板字符串
- 模板字符串用反引號標識:``
- 可以使用${} 添加變量腋颠,{}中也可以是函數淑玫,表達式
變量的解構賦值
- 解構賦值的規(guī)則:只要等號右邊的值不是對象或數組面睛,就會先將其轉換為對象叁鉴。數組的解構賦值
- 模式匹配:等號兩邊的模式相同,左邊的變量就會被賦予右邊的對應的值但壮。解構不成功時蜡饵,會被賦值為
unde?ned
胳施。 - 默認值:解構賦值允許有默認值舞肆,所以要胆绊,只有===unde?ned時,默認值才能生效
對象的解構賦值
- 屬性名字匹配:變量名與屬性名相同時才能取到正確的值仆抵,解構不成功镣丑,被賦值為
unde?ned
對象的解構賦值是將前者的值解構賦予后者:
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined
字符串解構賦值
- 字符串的解構賦值是默認將字符串轉換為類數組對象了數值與布爾值的解構賦值
- 如果等號右邊的值是數值和布爾值,那么會先轉換為對象金吗,再進行解構賦值摇庙。
對象字面量
- ES6允許在對象之中遥缕,直接寫變量单匣。屬性可以簡寫,如:
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
- 方法也可以簡寫码秉,省略function:
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
- ES6允許字面量定義對象時转砖,用表達式作為對象的屬性名,但是要將表達式放在方括號內
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
- 表達式也可以用于定義方法名
let obj = {
['h' + 'ello']() {
return 'hi';
}
};
obj.hello() // hi
箭頭函數
- ES6允許使用“箭頭”
(=>)
定義函數挑围,箭頭函數可以省略function
關鍵字
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
- 如果箭頭函數沒有參數或者有多個參數杉辙,就需要使用圓括號捶朵,如果只有一個參數蜘矢,可以將圓括號省略
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
- 箭頭函數的
this
指針指向的是定義時所在的對象,而不是使用時所在的對象 - 箭頭函數不可以當作構造函數综看,不可以使用
new
命令 - 不可以使用
arguments
對象品腹,該對象在函數體內不存在『毂可以使用rest參數代替
Import和Export
- ES6的模塊自動采用嚴格模式舞吭,不管有沒有在模塊頭部添加
‘use strict’
- 嚴格模式的限制有:
- 變量必須聲明后使用
- 函數的參數不能有同名的屬性不能對只讀屬性賦值
- 禁止this指向全局對象泡垃,ES6中頂層的this指向
unde?ned
export命令
- 模塊的功能主要由兩個命令構成:
export
和import
。 -
export
用于規(guī)定模塊的對外接口羡鸥,import
命令用于輸入其他模塊提供的功能 如果你需要在外部讀取到模塊內部的某個變量蔑穴,就必須使用export
輸出該變量
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
// 等同于
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
-
export
除了輸出變量惧浴,還可以輸出函數或類(class)
export function multiply(x, y) {
return x * y;
};
- 通常情況下存和,
export
輸出的變量就是本來的名字,但是可以使用as
關鍵字重命名
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
// 重命名后v2可以以不同的名字輸出兩次
-
export
命令規(guī)定的是對外的接口衷旅,必須與模塊內部的變量建立一一對應的關系
import命令
- 使用
export
定義了模塊的對接口以后捐腿,就可以通過import
命令來加載這個模塊了
import { firstName, lastName, year } from './profile.js';
-
import
命令接受一對大括號,里面指定要從其他模塊導入的變量名芜茵。大括號里面的變量名必須與被導入模塊對 外接口的名稱相同叙量。import
后面的from
指定模塊的文件位置,可以是相對位置九串,也可以是絕對位置绞佩。 - 如果想要重新命名,可以使用
as
關鍵字
import { lastName as surname } from './profile.js';
-
import
命令輸入的變量都是只讀的猪钮,不允許在加載模塊的腳本里面品山,改寫接口。但是可以改寫接口的屬性烤低。 -
import
是靜態(tài)執(zhí)行肘交,所以不能使用表達式變量。
export default命令
-
export default
就是輸出一個default
的變量或者方法扑馁,在import
輸入的時候允許為他命名為任意的名字涯呻。 - 一個模塊只能有一個默認輸出,因此
export default
命令只能使用一次腻要。所以复罐,import
命令后不需要加{},因為只能唯一對應到export default
的值
// modules.js
function add(x, y) {
return x * y;
}
export {add as default};
// 等同于
// export default add;
// app.js
import { default as foo } from 'modules';
// 等同于
// import foo from 'modules';
-
export default
命令其實是輸出一個叫做default
的值雄家,所以他的后面不能跟變量聲明的語句
// 正確
export var a = 1;
// 正確
var a = 1;
export default a;
// 錯誤
export default var a = 1;
裝飾器
- 修飾作用于類效诅,
- 修飾器函數的第一個參數是要修飾的目標類。修飾器可以接受參數趟济,相當于修改修飾器
function testable(isTestable) {
return function(target) {
target.isTestable = isTestable;
}
}
@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true
@testable(false)
class MyClass {}
MyClass.isTestable // false
- 修飾器對類的行為改變乱投,是代碼編譯時發(fā)生的。意味著修飾器能在編譯階段運行代碼顷编。 修飾器的本質就是編譯時執(zhí)行的函數
- 修飾器修飾類的屬性
- 修飾器的第一個參數是類的原型對象戚炫,第二個參數是所要修飾的屬性名,第三個參數是該屬性的描述對象
class Person {
@readonly
name() { return `${this.first} ${this.last}` }
}
function readonly(target, name, descriptor){
// descriptor對象原來的值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
}
readonly(Person.prototype, 'name', descriptor);
// 類似于
Object.defineProperty(Person.prototype, 'name', descriptor);
- 修飾器不能作用于函數的原因是:函數存在變量提升媳纬,導致函數實際執(zhí)行順序與書寫的不一致
Promise
- promise對象的兩個特點
- 對象的狀態(tài)不受外界影響嘹悼。
promise
有三種狀態(tài)叛甫,pending
(進行中)、fu?lled
(已成功)杨伙、rejected
(已失斊浼唷)。只有異步操作的結果可以決定當前的狀態(tài)限匣。 - 一旦狀態(tài)改變抖苦,就不會再改變,任何時候都可以得到這個結果米死。
promise
對象的狀態(tài)改變只有兩種可能: 從pending
變?yōu)?code>fu?lled和從pending
變成rejected
锌历。
- 對象的狀態(tài)不受外界影響嘹悼。
- promise的基本用法:
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
-
promise
構造函數接受一個函數作為參數,該函數的兩個參數分別是resolve
和reject
峦筒。 -
resolve
函數作用是將promise
對象的狀態(tài)變?yōu)槌晒课鳎惒讲僮鞯慕Y果作為參數傳遞出去。 -
reject
函數 的作用是將promise
的狀態(tài)變?yōu)槭∥锱纾惒讲僮鞯腻e誤作為參數傳遞出去卤材。 -
promise
實例生成后,可以使用then
方法來分別指定resolved
狀態(tài)和rejected
狀態(tài)的回調扇丛。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
- promise新建后就會立即執(zhí)行,then函數會進入異步隊列等候執(zhí)行
- Promise.prototype.then()
-
then
方法定義在原先對象promise.prototype
上尉辑。作用是為promise
實例添加狀態(tài)改變時的回調函數 -
then
方法的第一個參數是resolved
狀態(tài)的回調函數帆精,第二個參數(可選)是rejected
狀態(tài)的回調函數。then
方法的返回值是一個新的promise
實例隧魄,因此可以采用鏈式寫法卓练,在then
方法后再調用另一個then
方 法。
-
getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
- promise.prototype.catch()
-
Promise.prototype.catch
方法是.then(null, rejection)
或.then(unde?ned, rejection)
的別名购啄,用于指定發(fā)生錯誤時的回調函數襟企。
-
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 處理 getJSON 和 前一個回調函數運行時發(fā)生的錯誤
console.log('發(fā)生錯誤!', error);
});
- 如果沒有使用
catch
方法指定錯誤處理的回調函數闸溃,promise
對象拋出的錯誤就不會傳遞到外層代碼整吆。
因此建議在promise
對象后面要跟catch
方法拱撵,catch
方法返回的也是一個promise
對象辉川,接著還可以調用
then
方法。promise.prototype.?nally()
-
?nally
方法用于指定不管promise
對象最后狀態(tài)如何拴测,都會執(zhí)行的操作乓旗。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
// 不管promise最后的狀態(tài),在執(zhí)行完then或catch指定的回調函數以后集索,都會執(zhí)行finally方法指定的回調函數屿愚。
-
?nally
方法的回調不接受任何參數汇跨,也就是無法指定promise
的狀態(tài)是成功還是失敗。?nally
里面的操作是 與狀態(tài)無關的妆距,不依賴promise
的狀態(tài)穷遂。 - promise.all()
promise.all
方法用于將多個promise
實例,包裝成一個新的promise
實例娱据。
const p = Promise.all([p1, p2, p3]);
// Promise.all方法接受一個數組作為參數蚪黑,p1、p2中剩、p3都是 Promise 實例
// p的狀態(tài)由p1忌穿、p2、p3決定结啼,分成兩種情況掠剑。
// 只有p1、p2郊愧、p3的狀態(tài)都變成fulfilled朴译,p的狀態(tài)才會變成fulfilled
如果作為參數的promise
實例,自己定義了catch
方法糕珊,那么他被rejected
之后也不會觸發(fā)promise.all
的
catch
方法
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('報錯了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 報錯了]
// p1會resolved动分,p2首先會rejected,但是p2有自己的catch方法红选,該方法返回的是一個新的 Promise 實例澜公,p2指向的實際上是這個實例。該實例執(zhí)行完catch方法后喇肋,也會變成resolved坟乾,導致Promise.all()方法參數里面的兩個實例都會resolved,因此會調用then方法指定的回調函數蝶防,而不會調用catch方法指定的回調函數甚侣。
// 如果p2沒有自己的catch方法,就會調用Promise.all()的catch方法间学。