小白路程之----淺談ES6部分語法

曉月君發表於2018-08-11

一、新的變數宣告let和const

  • 新的變數宣告形成新的作用域區域叫,塊級作用域,即在一個{}內有let或者const宣告的變數,那麼這個變數就只會在這個{}內產生作用。

1、let宣告的注意事項

在ES6中,告別了單一的基礎變數的宣告var,迎來了兩個新的變數宣告,擁有塊級作用域的let以及常量宣告const,對於這新兩個變數宣告,在我看來是JS向C語言以及Java語言的學習。

  • 1、let宣告的變數在預編譯時不會提升。

    var變數在預編譯時會將宣告提升至程式碼開始的部分,但是不包括變數的賦值部分。而let直接不提升。因此,不可在let宣告的變數前面訪問變數。

console.log(a);//undefined
var a=1;
console.log(b);
let b=1;//ReferenceError:b is not defined
複製程式碼
  • 2、不能使用let重複宣告變數。var重複宣告變數會形成覆蓋,但是let不會,直接報錯。
var a=1;
var a=2;
console.log(a);//2
let b =1;
let b =2;
console.log(b);//SyntaxError: Identifier 'b' has already been declared
複製程式碼
  • 3、當let在{}內宣告時,會形成一個塊級作用域。在塊級作用域外無法呼叫其內的變數
  • 例如在下面的閉包函式內,由於i的作用域是整個函式,導致計數的變數i洩露為全域性變數,i與arr[0],arr[1],arr[2]三個函式處於並列狀態,當呼叫三個函式時,輸出的不是1、2、3,而都是i迴圈完成後的3。
function f(){
    var arr = [];
    for (var i = 0;i<3;i++){
        arr[i]=()=>i;
    }
    return arr;
}
var arr = f();
console.log(arr[0](),arr[1](),arr[2]());//3 3 3
複製程式碼

對於這個函式的處理,在let變數未出現時,需要使用將i的值傳遞給一個立即執行函式,或者將i本地化的方法來實現。但是let變數的塊級作用域使得這個函式的處理變得簡單起來,只需將for (var i = 0;i<3;i++)改成for (let i = 0;i<3;i++)即可。

  • 4、let的暫時性死區問題,即在let宣告的塊級作用域內它所宣告的變數就會繫結在這個區域內,不受外部影響。
var a = 1;
{
    console.log(a);
    let a=2;
}//ReferenceError: a is not defined
複製程式碼

2、const宣告的注意事項

  • 1、const宣告的是常量,不可更改,不可重複宣告。
const a=1;
a=2;//TypeError: Assignment to constant variable.
const b=1;
const b=2;//SyntaxError: Identifier 'b' has already been declared
複製程式碼
  • 2、const宣告的變數不會提升。
console.log(c);
const c=3;//ReferenceError: c is not defined
複製程式碼
  • 3、const命令也會形成一個塊級作用域,在作用域外無法訪問其內宣告的常量。
{const d=4;}
console.log(d);//ReferenceError: d is not defined
複製程式碼
  • 4、const無法宣告引用資料型別的常量。const只能保障宣告的資料在棧區中的值不變,堆區中的資料就無能為力了。
const a=[1,2,3];
a[2]=5;
console.log(a);//[ 1, 2, 5 ]
複製程式碼

二、字串模板

  • 在ES6中新增了字串模板,方便了變數以及字串在文字間的插入。
模板形式:`${value}`
使用模板字串:
var a = "Hello";
console.log(`你好的英文是:${a}。`);//你好的英文是:Hello。
原始字串:
var b = "Hello";
console.log('你好的英文是:'+b+'。');//你好的英文是:Hello。
複製程式碼
  • 需要注意的是模板字串的是兩個引號是反引號而不是單引號。

三、變數的解構賦值

1、字串的解構賦值

  • 在ES6中允許以以下的方式為b變數賦值。
let [a,b,c]=[1,2,3];
console.log(a,b,c)//3 2 1
複製程式碼
  • 解構賦值會將‘=’右邊的值賦予與其位置相對應的左邊的變數,而且允許使用ES6的新語法擴充套件運算子。
let [a,[b],c]=[1,[2,3],4];
console.log(a,b,c);//1 2 4
let [a,...b] = [1,2,3,4];
console.log(a,b);//1 [ 2, 3, 4 ]
複製程式碼
  • 若解構賦值的左右兩邊不是一一對應時,會導致解構失敗,而賦值undefined
let [a,b,c]=[1,,4];
console.log(a,b,c);//1 undefined 4
複製程式碼
  • 解構賦值允許設定預設值,當=右邊沒有相對應的值時,則給變數賦於預設值。
let [a=1,b=2]=[3,,];
console.log(a,b);//3 2
複製程式碼

2、物件的解構賦值

  • 物件的解構與陣列的最重要的不同在於,陣列需要按照元素的排列順序按位置賦值,而物件需要屬性與變數同名,才能正確賦值。
let {a,b}={b:'aaa',a:'bbb'};
console.log(a,b);//bbb aaa
複製程式碼
  • 與陣列一樣,物件的解構也可用於巢狀模式,但是格式不一樣。
a是按照陣列的格式解構的,b和c是按照物件解構的格式賦值的。
let {p:[a,{b,c}]}={p:['aaa',{c:'ccc',b:'bbb'}]};
console.log(a,b,c);//aaa bbb ccc
複製程式碼
  • 物件的解構也允許預設值,以及解構失敗也是undefined,但是注意undefined和null不同,null會是個有效的賦值
let {a=1,b=2,c=3,d}={a:'ccc',b:undefined,c:null};
console.log(a,b,c,d);//ccc 2 null undefined
複製程式碼

3、字串的解構賦值

  • 字串在解構賦值時會被轉換成類似陣列的物件。
let [a,b,c,d]='ABCD';
console.log(a,b,c,d);//A B C D
複製程式碼
  • 還可以對陣列物件的length屬性解構賦值。
let {length:a}='hello';
console.log(a);//5
複製程式碼

4、解構賦值的用途

  • 交換變數的值
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x,y)//2 1
複製程式碼
  • 函式引數的傳值與返回。
function f([x,y,z]){
    x+=1;
    y+=1;
    z+=1;
    return [x,y,z]
}
let [a,b,c]=f([1,2,3]);
console.log(a,b,c);//2 3 4
複製程式碼

四、字串操作方法的擴充套件

1、charAt

  • 返回字串指定位置的字元。
var str='hello';
console.log(str.charAt(0));//h
複製程式碼

2、trim

  • 對字串首尾兩邊的空格進行處理,不修改原字元,返回處理過的字串,對字串內的空格不進行處理。
  • trim:去除字串左右兩邊的空格,
  • trimLeft:去除字串的左空格,
  • trimRight:去除字串的右空格。
var str = "  a b c ";
console.log(str);//  a b c 
console.log(str.trim());//a b c
console.log(str.trimLeft());//a b c 
console.log(str.trimRight());//  a b c
console.log(str);//  a b c 
複製程式碼

3、repeat

  • 重複原字串,可設定重複次數,不修改原字串,返回修改過後的字串。
var str = '123';
console.log(str.repeat(2));//123123
console.log(str.repeat(0));//空
console.log(str);//123
複製程式碼

4、includes

  • 判斷是否含有匹配的字串,而且可以自動匹配空格,返回true|false,一般和正規表示式一起用。
var str = "asdasdas sd ad"
console.log(str.includes('asd'));//true
console.log(str.includes('as sd'));//true
console.log(str.includes('assd'));//false
複製程式碼

5、strartsWith和endsWidth

  • strartsWith:判斷字串的開始字串。
  • endsWidth:判斷字串的結束字串。
var str = "asd dsad";
console.log(str.startsWith('asd'));//true
console.log(str.startsWith('asdds'));//false
console.log(str.endsWith('ad'));//true
console.log(str.endsWith('ad '));//false
複製程式碼

6、padStart和padEnd

  • 字串補全長度的方法,不夠設定長度的用指定字元補全
  • padStart:如果字串不夠指定長度,在頭部補全
  • padEnd:如果字串不夠指定長度,在尾部補全
var str = "asdas dsad";
console.log(str.padStart(15,'$'));//$$$$$asdas dsad
console.log(str.padEnd(15,'$'));//asdas dsad$$$$$
console.log(str);//asdas dsad
複製程式碼

7、for...of迴圈遍歷

  • 迴圈遍歷陣列字串,或者新的資料結構set。其迴圈的不是陣列或字串的下標,而是相對應的陣列或字串的值。
var str=['a','b','c','d'];
for (var i of str){
    console.log(i);
};//宣告的i變數是迴圈時與陣列位置相對應的值,a b c d
var a='hello';
for (var i of a){
    console.log(i);
};//宣告的i變數是迴圈時與字串位置相對應的值,h e l l o
複製程式碼

五、函式的擴充套件

1、箭頭函式

箭頭函式的普通形式和原本的函式並沒有多大的差別,只是在部分簡寫的形式下,箭頭函式更加的方便,以及簡潔。

  • 1、普通形式
  普通函式:function f(形參){表示式;return 返回值;}
  箭頭函式:var f=(形參)=>{表示式;return 返回值} 
複製程式碼
  • 2、當函式中只有一個形參時,箭頭函式的形參的()可以省略。但是沒有引數時,引數的括號不可以省略,見第三條。
  普通函式:function f(x){return x*x;} 
  箭頭函式:var f=x=>{return x*x;} 
複製程式碼
  • 3、函式體只有一條非return語句時,箭頭函式的{}也可以省略。
  普通函式:function f(){console.log("Hello")} 
  箭頭函式:var f=()=>console.log("Hello"); 
複製程式碼
  • 4、當函式體只有一條return返回語句時,箭頭函式的return語句亦可以省略。
 普通函式:function f(x){return x*x;} 
 箭頭函式:var f=x=>x*x 
複製程式碼
  • 5、在一些陣列的方法中可見,箭頭函式的簡便之處。
var arr = [1,2,3]
普通函式:
var rs = arr.map(function(item){
   return item +=10;
})
 箭頭函式:
var rs = arr.map(item => item+=10;)
console.log(rs)//[ 11, 12, 13 ]
複製程式碼
  • 由此可見,在一些對於資料的簡短處理上,箭頭函式不僅可以更清晰的顯示資料關係以及用更簡潔的表示式處理資料。

2、函式引數的預設值

  • 在ES6中可以為函式的指定引數設定預設值。
function f(x=1,y=2){
    console.log(x+y);
}
f();//3
f(3)//5
f(3,3)//6
複製程式碼
  • 引數變數是預設宣告的,不可以重複宣告。
function f(x=2){
    let x=1;
}
f();//SyntaxError: Identifier 'x' has already been declared
複製程式碼
  • 若函式內設定預設引數,函式宣告時不能有同名引數
function f(x,x,y){};
f();//不報錯
function h(x,x,y=1){}
h();//SyntaxError: Duplicate parameter name not allowed in this context
複製程式碼

3、函式引數的擴充套件運算子賦值

  • ES6中,新增的擴充套件運算子在函式的傳參的過程中也可使用。與arguments相比,擴充套件運算子的形式更簡潔。
function f(...val) {
    let sum = 0;
    for (var i of val) {
        sum += i;
    }
    return sum;
}
console.log(f(2, 5, 3));//10
複製程式碼

六、陣列的擴充套件

1、擴充套件運算子

  • 陣列的擴充套件運算子的應用:複製陣列,合併陣列,與解構賦值結合,將字串轉化成陣列...

對於陣列的賦值,是深拷貝:

var str=[1,2,3];
var str1=[...str];
console.log(str1)//[ 1, 2, 3 ]
str1[1]=6;
console.log(str)//[ 1, 2, 3 ]
console.log(str1)//[ 1, 6, 3 ]
複製程式碼

合併陣列:

var str2=[...str,...str1]
console.log(str2);//[ 1, 2, 3, 1, 6, 3 ]
複製程式碼

與解構賦值結合:

const [f, ...g] = [1, 2, 3, 4, 5];
console.log(f);//1
console.log(g);//[ 2, 3, 4, 5 ]
複製程式碼

將字串轉化成陣列:

var str='asdfg';
console.log([...str]);//[ 'a', 's', 'd', 'f', 'g' ]
複製程式碼

2、Array.from()

  • 這個方法時Array構造器的靜態方法,可以將類陣列物件轉化成真正的陣列。
let arr={0:"a",1:"b",2:"c",length:3}
let arr1=Array.from(arr)
console.log(arr1);//[ 'a', 'b', 'c' ]
複製程式碼

3、Array.of()

  • 將一組值轉化成陣列。
let arr=Array.of(1,2,3,4);
console.log(arr);//[ 1, 2, 3, 4 ]
複製程式碼

4、find()和findIndex()

  • find(),找出第一個符合條件的陣列元素,並返回,找不到則返回undefined。
  • findIndex(),返回第一個符合條件的陣列元素的索引,找不到則返回-1。
格式:
arr.find(function(item,index){
  return 條件;
})//findIndex()與find()的格式一樣
複製程式碼
let str=['d','s','a','b',2,3];
find()方法:
let rs=str.find(item=>item=='a')
let rs1=str.find(item=>item=='c')
console.log(rs);//a
console.log(rs1);//undefined,未找到返回undefined
findIndex方法:
let rs2=str.findIndex(item=>item>2)
let rs3=str.findIndex(item=>item=='c')
console.log(rs2);//5
console.log(rs3);//-1,未找到返回-1
複製程式碼

5、fill()

  • 在陣列內填充指定的值或符號,或者在指定位置填充值或者符號。
格式:arr.fill(值或符號);
格式:arr.fill(值,起點,終點);包括起點,不包括終點
let arr=Array(5);
let rs=arr.fill('a');
console.log(rs);//[ 'a', 'a', 'a', 'a', 'a' ]
let rs1=arr.fill('b',1,3)
console.log(rs1);[ 'a', 'b', 'b', 'a', 'a' ]
複製程式碼

6、keys()和valueOf()

  • 都用於陣列的遍歷,一般和for...of迴圈遍歷一起使用,它們都返回一個遍歷器物件,keys()是對鍵名的遍歷、valueOf()是對鍵值的遍歷。
var str=['a','b','c','d'];
for (let i of str.keys()){
    console.log(i);
}//0 1 2 3
for (let i of str.valueOf()){
    console.log(i);
}//a b c d
複製程式碼

7、includes()

  • 判斷元素是否在陣列中存在。返回值是 true | false。
var str=['a','b'];
console.log(str.includes('a'));//true
複製程式碼

七、物件的擴充套件

1、屬性名擴充套件

  • 在ES6中,對於物件的屬性名可以用更簡潔的方式表達,而且可以使用表示式的方法,雖然表示式的方法很少使用。
  • 當屬性名和屬性變數相同時,可以省略。
  • 物件內方法的function宣告可以省略。
let name='zz';
let obj={
    name,//屬性名和屬性值一致,可以省略
    ['a'+'g'+'e']:12,//屬性名用表示式的方式
    say(){
        console.log(`我是:${this.name},今年${this.age}歲了。`);
    }
}
obj.say();//我是:zz,今年12歲了。
複製程式碼

2、Obect.getOwnProertyDescriptor();

  • 獲取一個物件中某個屬性的詳細資訊。
let obj = { f: 1 };
console.log(Object.getOwnPropertyDescriptor(obj, 'f'));
{ value: 1,
  writable: true,
  enumerable: true,
  configurable: true }
複製程式碼

3、Object.defineProperty()和Object.defineProperties()

  • Object.defineProperty()精細化設定一個物件的屬性。
  • Object.defineProperties()一次性精細化設定多個物件的屬性。格式和Object.defineProperty()一樣。
var obj={};
Object.defineProperty(obj,'name',{
    value: 'abcd',//屬性值
    writable: false,//是否可以修改
    enumerable: true,//是否可以列舉
    configurable: false//是否可以刪除
})
console.log(obj.name);//abcd
delete obj.name;
console.log(obj.name);//abcd未刪除成功
複製程式碼

4、getOwnPropertyNames()

  • 獲取自身屬性名,以陣列的格式返回
var obj={
    name:'zzz',
    age:222
};
console.log(Object.getOwnPropertyNames(obj));//[ 'name', 'age' ]
複製程式碼

5、Object.keys()和Object.values()

  • Object.keys()獲取物件的屬性名,Object.values()獲取物件的屬性值,都是以陣列的格式返回,一般和for...of迴圈遍歷一起用。
var obj={
    name:'zzz',
    age:222
};
console.log(Object.keys(obj));//[ 'name', 'age' ]
console.log(Object.values(obj));//[ 'zzz', 222 ]
複製程式碼

6、與繼承相關的方法

  • 1、Object.create():使用Object.create()比較適合對字面量物件的繼承。
  • 2、Object.getPrototypeOf():獲取建立這個物件的那個構造器的prototype屬性。 如圖所示:
    小白路程之----淺談ES6部分語法
  • 3、Object.preventExtensions():不允許新增,但是可以修改和刪除。
  • 4、Object.seal():不允許新增,也不允許刪除,但是可以修改。
  • 5、Object.freeze():不允許新增,也不允許刪除和修改。

7、Object.assign

  • 用於物件的合併,將源物件的所有的可列舉屬性,複製到目標物件。
格式:
Objext.assign(目標物件,源物件,源物件...)
複製程式碼
let obj={};
let obj1={name:'zz'};
let obj2={age:21};
console.log(Object.assign(obj,obj1,obj2));//{ name: 'zz', age: 21 }
複製程式碼
  • 1、Objext.assign()不能拷貝源物件繼承過來的屬性以及不可列舉的屬性。
  • 2、Objext.assign()會把源物件原型上面的發展也拷貝過來。
  • 3、Objext.assign()是淺拷貝。

8、物件擴充套件運算子

  • 與陣列的擴充套件運算子類似,可以拷貝物件,但是是淺拷貝。可以合併物件,以及解構賦值等。

八、Set與Maps資料結構

Set資料結構

  • set類似於陣列,是一種集合,但是裡面的值都是唯一的,沒有重複。
  • 存陣列時,空的位置會用undefined代替,但是隻有第一個空的位置會有undefined,其後空的位置自動去除。
  • 建立時必須使用new建立一個set資料
  • 格式:var set1 = new Set();

存資料的兩種方式如下:

方式一,宣告時直接儲存:
var set2 = new Set([1,2,2,3,3,4,4,5,'true','true']);
方式二,利用set.add()方法儲存:
set2.add(false).add('zz').add('zz')
console.log(set2);//Set { 1, 2, 3, 4, 5, 'true', false, 'zz' }
console.log(set2.size);//8,獲取元素個數
複製程式碼
  • 還可以存放物件,可以通過set.add的方式,或者直接儲存的方式。但是要記得直接儲存時,需要在物件外加上一個[],如下所示。
方式一:
var obj = {
    name:"jj",
    say:function(){console.log('aaaaa')}
}
set2.add(obj);
console.log(set2);//Set {1,2,3,4,5,'true',false,'zj',{ name: 'jj', say: [Function: say] } }
方式二:
var set3 = new Set([ {name:'zj'} ]) 
console.log(set2);//Set { { name: 'zj' } }
複製程式碼
  • set的遍歷只可以使用for..of或者for..each,不能使用for..in,for..in遍歷是通過鍵值對的鍵來取值的,而set裡無法通過與值相對應的鍵來呼叫資料。
var set4 = new Set(['a','b','c','d','a','c','sad','as','das','sda']);
方式一:
set4.forEach(item=>console.log(item));//a b c d sad as das sda
方式二:
for(var i of set4){
    console.log(i);
}//a b c d sad as das sda
複製程式碼
  • set在瀏覽器內雖然有下標表示資料的鍵,但是set不是陣列,是一個偽陣列,不可像陣列一樣通過下標取值,但是可以通過Array.from()的方式將set暫時轉換成陣列,並可通過下標來呼叫其內的資料。 console.log(Array.isArray(Array.from(set2)));//true

  • Array.from()轉換,只能將set資料結構暫時轉換成陣列,因此不可轉換後再呼叫。

使用方式如下:

方式一:
for(var p in Array.from(set4)){
    console.log(Array.from(set4)[p]);
}//a b c d sad as das sda
方式二:
for(var p in [...set4]){
    console.log(Array.from(set4)[p]);
}//a b c d sad as das sda
複製程式碼
  • 利用set,達到陣列去重的,方法如下:
var arr = [1,2,3,,3,4,5,234,,4,'sad','sad',true]
var arr1 = [...(new Set(arr))];
console.log(arr1);//[ 1, 2, 3, undefined, 4, 5, 234, 'sad', true ]
複製程式碼

Map資料結構

  • map資料結構類似於物件,存放鍵值對,使用時和set一樣必須使用new建立。 格式:var m = new Map();
  • 存放資料,相同屬性名,後面的會覆蓋前面的,非數字必須使用''或者“”。
  • 前面是鍵值對的“鍵”,後面是鍵值對的“值”,鍵值對之間用逗號隔開。
  • []內只存放一個資料時,根據在逗號的前後判斷是鍵或者值,未存的資料預設為undefined
  • 可以存放任何資料型別
var m = new Map([
    [1,'asd'],//被覆蓋
    ['a','ad'],
    [1,'12'],//  1 => '12',字串12
    [2,12],//  2 => 12,
    [[1,2,3],{naem:'zj'}],
    [,3],//undefined => 3,
    [3,]//3 => undefined,
]);
m.set(false,'asd');
複製程式碼
  • 通過屬性的鍵來獲取屬性值
m.get(undefined);//3
m.get([1,2,3]);//獲取不到物件,get()是比較棧區中的地址,而不是堆區中的資料
複製程式碼

因此如果想要訪問引用資料型別的鍵所對應的值,需要用如下方式:

var arr = [1,2,3];
m.set(arr,'asd');
m.get(arr);//執行結果:"asd"
複製程式碼

九、類Class

  • class建立物件,類名首字母大寫,使用大駝峰命名法則。
  • {}中只能寫方法,不需要使用關鍵字。
  • 方法與方法之間沒有逗號,不是鍵值對。

格式如下:

class 類名{                 
  constructor(引數){       
    this.屬性 = 引數;   
  }
  method(){  }//物件中的簡寫方法
  static met(){  }//靜態方法,可以直接呼叫
}
複製程式碼
class Person{
    constructor(name,age){
        this.name = name;
        this.age =age;
    }
    say(){
         console.log(`我是${this.name},今年${this.age}歲了。`);
    }
    static eat(){   //靜態方法,可以直接呼叫
        console.log('eat...');
    }
}
var p1 = new Person("zz","21");
p1.say();//我是zz,今年21歲了。  
Person.eat();//eat...
複製程式碼
  • class類之間可以使用extends實現繼承。
  • 利用super(屬性名,屬性名...),繼承父元素的屬性。
  • 方法會自動在父元素和子元素之間繼承。
class Student extends Person{
    constructor(name,age,adds){
        super(name,age);
        this.adds = adds;
    }
    show(){
        console.log(`我是${this.name},現在在${this.adds}。`);
    }
}
var s1 = new Student('zz','22','家');
s1.say();//我是zz,今年22歲了。
s1.show();//我是zz,現在在家。
複製程式碼

十、Promise物件

簡單理解promise是一種非同步程式設計的解決方案。所謂 promise,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。從語法上說,Promise 是一個物件,從它可以獲取非同步操作的訊息。Promise提供統一的 API,各種非同步操作都可以用同樣的方法進行處理。

1、四大術語

  • 解決(fulfill ):指一個 promise 成功時進行的一系列操作,如狀態的改變、回撥的執行。雖然規範中用 fulfill 來表示解決,但在後世的 promise 實現多以 resolve 來指代之。
  • 拒絕(reject ):指一個 promise 失敗時進行的一系列操作。
  • 終值(eventual value ):所謂終值,指的是 promise 被解決時傳遞給解決回撥的值,由於promise 有一次性的特徵,因此當這個值被傳遞時,標誌著 promise 等待態的結束,故稱 之終值,有時也直接簡稱為值(value)。
  • 據因(reason ):也就是拒絕原因,指在 promise 被拒絕時傳遞給拒絕回撥的值。

2、三種狀態

  • 等待態(Pending)處於等待態時,promise 需滿足條件:可以遷移至執行態或拒絕態。
  • 執行態(Fulfilled)處於執行態時,promise 需滿足條件:(1)不能遷移至其他任何狀態,(2)必須擁有一個不可變的終值。
  • 拒絕態(Rejected)處於拒絕態時,promise 需滿足條件:(1)不能遷移至其他任何狀態,(2)必須擁有一個不可變的據因。

3、兩種事件

對於三種狀態,有兩種轉換方向。

  • 如果是 pending --> fulfiied,就會觸發 onFulFilled 事件
  • 如果是 pendeing --> rejected,就會觸發 onRejected 事件

4、一個物件

  • promise物件

promise的基本用法

基本格式:

let pro=new Promise(function(resolve,reject){
  if(/*非同步操作成功*/){
    resolve("ok");//狀態從 pending --> fullFilled時執行的函式。傳遞終值(value)。
  }else{
    reject("not");//狀態從 pending --> rejected執行的函式。傳遞據因(reason)。
  }
})
複製程式碼

then方法

針對事件的註冊,promise物件提供了then方法。 格式如下:promise.then(onFulfilled,onRejected)

  • 針對 onFulFilled,會自動提供一個引數,作為終值(value)
  • 針對 onRejected,會自動提供一個引數,作為據因(reason)
let p1=new Promise(function(resolve,reject){
    let n=Math.random();
    if(n>0.5){
        resolve('ok')
    }else{
        reject('error')
    }
})
p1.then(function(res){<!--成功時,呼叫的函式-->
    console.log(res);<!--輸出傳遞的引數-->
    console.log("響應pending-->fulfined轉換事件");
},function(err){<!--失敗時,呼叫的函式-->
    console.log(err);<!--輸出傳遞的引數-->
    console.log("響應pending-->rejected轉換事件");  
})
console.log(p1);
當非同步操作成功時:
<!-- Promise { 'ok' }
ok
響應pending-->fulfined轉換事件 -->
當非同步操作失敗時:
<!-- Promise { <rejected> 'error' }
error
響應pending-->rejected轉換事件 -->
複製程式碼

catch方法

  • 用於註冊 onRejected 回撥。
  • .catch()方法其實是 then 的簡寫,then(null,callback)
  • then 方法呼叫之後,仍然返回的是 promise 物件,所以可以鏈式呼叫,如下:
p1.then(res=>console.log(res)).catch(err=>console.log(err))
複製程式碼
  • 在使用 promise 物件時,一般這麼描述,非同步操作成功的時候,走 then,失敗的時候就走 catch。

所以上面的p1的回撥事件可以寫成如下形式:

p1.then(function(res){
    console.log(res);
    console.log("響應pending-->fulfined轉換事件");
}).catch(function(err){
    console.log(err);
    console.log("響應pending-->rejected轉換事件");  
})
複製程式碼

相關文章