ES6基礎知識筆記彙總(學習微信前端教程)

1. let 關鍵字:用來聲明變量;

 彌補Var不足之處:

(1)let聲明的變量僅僅在自己的塊級作用域起作用,出了這個作用域就不起作用。任何一對花括號{}中的語句都屬於一個塊,在花括號裏面用let定義的所有變量在花括號外都是不可見的,稱爲塊級作用域。

(2)var聲明變量時候會出現“變量提升”的現象;用let就不會;

使用let注意:

(1)同一個塊級作用域內,不允許重複聲明同一個變量;

(2)函數內不能用let重新聲明函數的參數

2. const關鍵字:用來聲明常量的;

常量的特點

(1)不可修改;

(2)只在塊級作用域起作用(與let關鍵詞一樣);

(3)不存在變量提升,必須先聲明後使用(與let關鍵詞一樣);

(4)不可重複聲明同一個變量;

(5)聲明後必須要賦值;

Const常量是個對象:傳址賦值

傳址:在賦值過程中,變量實際存儲的是數據地址(對數據的引用),而不是原始數據或者數據的拷貝;

 var student1={“name”:”張三”};

var student2=student1;

Student2.name=”李四”;

console.log(student1);//結果:{name:”李四”}

console.log(student2);//結果:{name:”李四”}

3. ES6兼容問題

語法解析轉換工具:babel,jsx,traceur,es6-shim等

各大轉換工具、JavaScript解析引擎對ES6的支持程度情況:http://kangax.github.io/compat-table/es6

4. 新特性--解構賦值

解構:按照一定模式,從數組和對象中提取值,對變量進行賦值;

變量的賦值:

var [a,b,c]=[1,2,3];

數組的解構賦值:

(1)解構賦值可以嵌套的

(2)不完全解構:左邊與右邊不完全一樣的時候,只會給模式匹配成功的部分賦值;

(3)賦值不成功,變量的值爲undefined(相當於只聲明,沒賦值);

(4)允許默認值:var [a,b,c=3]=[1,2];

注意:當新的值爲undefined時,不會覆蓋默認值;

對象的解構賦值:

var {a,b,c}={“a”:1,”b”:2,”c”:3};

(1) 對象的賦值不會受到屬性的排列次序影響(數組會受影響);變量名和屬性名一致,纔會賦值成功;

(2) 找不到與之匹配的屬性,則賦值不成功,輸出 undefined;

(3) 對象解構賦值也可以嵌套;

(4) 可以指定默認值;

字符串的解構賦值:

var [a,b,c,d,e,f]=”我就是前端君”;

解構賦值的用途:

(1)交換變量的值

var x=1,y=2;

[x,y]=[y,x];

(2) 提取函數返回的多個值

函數只能返回一個值,我們可以將多個值裝在一個數組或對象中,再解構賦值快速提取其中的值;

(3) 定義函數變量

(4) 函數參數的默認值設定

(5) 函數參數的定義

5.字符串的擴展

新特性:模板字符

<script type="text/javascript">
    let name="Jack";
    let age="8歲";
   let str=`write once,run anywhere`;
   let ss=`My name is${name},I am${age}`;
   alert(ss);
</script>

(1) 可以定義多行字符串:所有的空格和縮進都會被保留在輸出中;

(2) ${ }中可以放任何的JavaScript表達式;

${}中可以是運算表達式:${a+b };

${}中可以是對象的屬性: var obj={“a”:1,”b”:2} --${obj.a+obj.b};

${}中可以是函數的調用:${fn()};

新特性:標籤模板 常用來實現過濾用戶的非法輸入和多語言轉換;

標籤:指一個函數,一個專門處理模板字符串的函數;

<script type="text/javascript">
    let name="張三";
    let height=1.8;
    tagFn`他叫${name},身高${height}`;
    function tagFn(arr,v1,v2) {
        console.log(arr); //結果: ["他叫", ",身高", "米", raw: Array(3)]
        console.log(v1);//張三
        console.log(v2);//1.8
    }

</script>

函數參數:第一個參數arr是數組類型,內容是除模板字符串除了${}以外的其他字符;v1是變量name的值;v2是變量height的值;

新特性:repeat函數

repeat()函數:將目標字符串重複N次,返回一個新的字符串,不影響目標字符串;

<script type="text/javascript">
    let name="張三";
    let name2=name.repeat(3);
    console.log(name); //結果:張三
   console.log(name2);//結果:張三張三張三
</script>

新特性:include

Include()函數:判斷字符串中是否含有指定的字符串,返回true表含有,false表示未含有;第二個參數選填,表示開始搜索的位置;

IndexOf()函數:通過返回是否爲-1判斷是否含有指定子字符串;

新特性:startsWith函數

StartWith()函數:判斷指定的字符串是否出現在目標字符串的開頭位置,第二個參數選填,表示開始搜索的位置;

新特性:endWith函數

endWith()函數判斷指定的字符串是否出現在目標字符串的尾部位置,第二個參數選填,表示針對前N個字符;

新特性:codePointAt函數

JavaScript無法正確讀取四字節字符,codePointAt方法可以正確識別四個字節的字符,並正確返回碼點的十進制;

charAt():返回指定位置的字符;

新特性:fromCodePointAt函數

fromCodePointAt()函數:函數參數是一個字符對應的碼點,返回的結果就是對應字符;4字節字符也能實現;

新特性:String.raw函數

String.raw():返回字符串最原始的樣貌,即使字符串中含有轉義符,都直接輸出;

Console.log(String.raw`hellp\nworld`);

6.數值擴展  

全局函數移植到其他對象下:慢慢減少全局性函數,把全局函數合理地規劃到其他對象下,漸漸實現語言的模塊化;

被移植的函數-新特性:Number.isNaN  判斷傳入的是否非數值

isNaN:is not a number)

傳統的isNaN函數會把非數值參數轉化成數值再進行判斷,而Number.isNaN只對數值有效,非數值類型參數一律返回false;(注意:當返回false時:不一定是一個數值,也可能是非數值類型的參數)

被移植的函數-新特性:Number.isFinite函數  檢查一個數值是否非無窮

非數值類型參數一律返回false,所以返回false時:不一定是一個非無窮,也可能是非數值類型參數;

被移植的函數-新特性:Number.parseInt 解析一個字符串,返回一個整數

被移植的函數-新特性:Number.parseFloat 解析一個字符串,返回一個浮點數

新增的函數-新特性:Number.isInteger  判斷是否爲整數(注意:在JavaScript內部,對整數和浮點數採用一樣的存儲方式,小數點後面是0的浮點數,會被認爲是整數)

新增的函數-新特性:極小常量Number.EPSILON 定義一個極小的數值

作用:用來判斷浮點數的計算誤差,如果浮點數的計算得到誤差 不超過Number.EPSILON 的值,就表示接受這樣的誤差;

安全整數  JavaScript能準確表示整數在-2^53到2^53之間,超過這個範圍,無法精確表示這個值,稱爲不安全;

Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER

判斷是否超過安全範圍,用Number.isSafeInteger進行判斷

Math對象新增17個函數

Math.trunc函數:用於去除一個數的小數部分,返回整數部分;

Math.sign函數:用來判斷一個數到底是正數、負數、還是零;參數是正數 結果返回1,參數是負數 返回-1,參數是0 返回0 ,參數是非數值類型的參數 返回NaN;

Math.cbrt函數:用於計算一個數的立方根;

Math.acosh(x) 返回 x 的反雙曲餘弦。
Math.asinh(x) 返回 x 的反雙曲正弦。
Math.atanh(x) 返回 x 的反雙曲正切。
Math.clz32(x) 返回 x 的 32 位二進制整數表示形式的前導 0 的個數。
Math.sinh(x) 返回x的雙曲正弦。
Math.cosh(x) 返回 x 的雙曲餘弦。
Math.expm1(x) 返回 eˆx - 1。
Math.fround(x) 返回 x 的單精度浮點數形式。
Math.hypot(...values) 返回所有參數的平方和的平方根。
Math.imul(x, y) 返回兩個參數以 32 位整數形式相乘的結果。
Math.log1p(x) 返回 1 + x 的自然對數。
Math.log10(x) 返回以 10 爲底的x的對數。
Math.log2(x) 返回以 2 爲底的 x 的對數。
Math.tanh(x) 返回 x 的雙曲正切。

7. 數組擴展

Array.of()函數 將一組值轉換成數組;

Array.from()函數 將類似數組的對象或者可遍歷的函數轉換成真正的數組;將字符串轉換成數組;

實例方法:

find()函數:找出數組中符合條件的第一個元素;不符合條件返回undefined;

<script type="text/javascript">
    let arr=[1,2,4,5];
    arr.find(function (value) {
        return value>2;
    })  // 結果:4

</script>

findIndex()函數:返回符合條件的第一個數組成員的位置;不符合條件返回-1;

fill()函數:用指定的值,填充到數組;

fill函數的參數會把原數組的每個元素填充成指定的參數。

<script type="text/javascript">
   let arr=[1,2,3];
   arr.fill(4,1,3);//第二個參數和第三個參數:從第1個位置到第3個位置之前填充數字4
</script>

entries()函數: 對數組的鍵值進行遍歷,返回遍歷器,可以用for...of對其進行遍歷;

<script type="text/javascript">
  for(let [i,v] of ['a','b'].entries()){
    console.log(i,v);
  }
</script>

keys()函數:對數組的索引進行遍歷,返回遍歷器;

value()函數:對數組的元素進行遍歷,返回遍歷器;

數組推導:用簡潔的寫法,直接通過現有的數組生成新函數;(有些瀏覽器不支持推導,可以火狐瀏覽器)

<script type="text/javascript">
 let arr1=[1,2,3,4];
 let arr2=[for(i of arr1) if(i>3) i];
 console.log(arr2);
</script>

8. 對象擴展

<script type="text/javascript">
 let name="lisa";
 let age="18歲";
 let he={name,age};   //ES6對象的屬性寫法
 console.log(he);
 let he2={
     say(){
         alert("這是ES6的表示法");   //ES6對象的方法表示法
     }
 };
 he2.say();
</script>

屬性名可以是表達式:用字面量定義一個對象時,可以用表達式作爲對象的屬性名或者方法名;

<script type="text/javascript">
 var f="first";
 var n="Name";
 var s="say";
 var h="Hello";
 var person={
     [f+n]:"zhang",
     [s+h](){
         return "你好嗎";
     }

 };
 console.log(person.firstName);
 console.log(person.sayHello());
</script>

 

新增函數:

Object.is()函數:比較兩個值是否嚴格相等,或者說全等;

Object.assign()函數:將源對象的屬性賦值到目標對象上;對象屬性出現相同名字,後面的屬性值就會覆蓋前面的屬性值;(可完成效果:給對象添加屬性和方法,克隆對象,合併多個對象,爲對象的屬性指定默認值)

Object.getPrototypeOf()函數:獲取一個對象的prototype屬性;

Object.setPrototypeOf()函數:設置一個對象的prototype屬性

模擬面向對象編程有幾個關鍵步驟:

1、構造函數;

2、給prototype對象添加屬性和方法;

3、實例化;

4、通過實例化後的對象調用類的方法或者屬性。

9. 函數擴展

參數的默認:默認參數一定放到最後,有默認值的參數後面不能再跟不需默認值的參數;

<script type="text/javascript">
 function person(name='zhang',age="15") {  //指定默認值
     console.log(name,age);
 }
 person();
 person("Lili",18);
</script>

rest參數:在實參中,除了第一個參數以外,剩餘的參數都會被...values獲取到;rest參數必須是函數的最後一個參數,後面不能再跟其它參數;

<script type="text/javascript">
 function sum(result,...values) {    
     console.log(values);
     values.forEach(function (v,i) {
         result+=v;
     });
 console.log(result);
 }
 let res=0;
 sum(res,1,2,3,4);
</script>

擴展運算符  ...(三個點)  一般結合數組使用,把數組的元素用逗號分隔開來,組成一個序列,將一個數組轉成一個對應的參數數列;

箭頭函數:=>)一種全新的定義函數的方式:第一個a代表傳進去的參數,箭頭=>後面的a表示函數體;

<script type="text/javascript">
 let sum=a=>a;
 console.log(sum(5));
</script>

傳入兩個參數:如果參數超過一個,需要用小括號()括起來,函數體語句超過1條,需要用大括號{}括起來;

<script type="text/javascript">
 let sum=(a,b)=>{return a+b};
 console.log(sum(4,5));
</script>

▲箭頭函數的this指向定義時的this對象,而不是執行時的this對象;

10. 全新數據類型

JavaScript數據類型:

String 字符串類型

Number 數字類型  

Object 對象類型

Boolean布爾值類型  

Undefined未定義

全新數據類型:Symbol 解決對象的屬性名衝突

即使參數一樣,描述一樣,得到的兩個值也是不相等的;

1)當symbol值作爲對象的屬性名的時候,不能用點運算符獲取對應的值,一定要用中括號[];

(因爲點運算會導致JavaScript把後面的屬性名理解爲一個字符串類型,而不是symbol類型)

<script type="text/javascript">
 let name=Symbol();
 let person={
     [name]:"張三"
 };
 console.log(person[name]);  //張三
 console.log(person.name);  //undefined
</script>

(2)symbol類型的值作爲屬性名的時候,該屬性不會出現在for...in和for...of中,也不會被Object.keys()獲取到;

<script type="text/javascript">
 let name=Symbol();
 let person={
     [name]:"張三",
     age:18
 };
 console.log( Object.keys(person));  //["age"]
 for(let key in person){
     console.log(key);          //age
 }
</script>

(3)getOwnPropertySymbols()函數  會找到symbol類型的屬性並且返回一個數組,數組成員就是symbol類型的屬性值;

<script type="text/javascript">
 let name=Symbol("name");
 let age=Symbol("age");
 let person={
     [name]:"張三",
     [age]:19
 }
console.log(Object.getOwnPropertySymbols(person)); //[Symbol(name), Symbol(age)]
</script>

(4)Reflect.ownKeys()  獲取所有類型的屬性

<script type="text/javascript">
 let person={
     [Symbol('name')]:"張三",
     "age":30
 };
 console.log(Reflect.ownKeys(person));  //["age", Symbol(name)]
</script>

(5)Symbol.for()函數 根據參數名,去全局環境中搜索是否以該參數爲名的symbol值,有就返回,沒有就以該參數名來創建一個新的symbol值;Symbol.for()創建的symbol值會被登記在全局環境中,供以後Symbol.for()來搜索;

(6)Symbol.keyFor()函數  返回一個以登記在全局環境的symbol值(被Symbol.for()創建的)的key,沒有就返回undefined。

11. 新特性 Proxy代理  將一個對象交給Proxy代理,然後通過編寫處理函數,來攔截目標對象的操作;

<script type="text/javascript">
 let person={"name":"張三"};

 var pro=new Proxy(person,{
     get:function (target,property) {
         return "李四"
     }
 });
    console.log(pro.name);           //李四
</script>

set方法  用於攔截對對象的寫操作;

ownKeys攔截操作,攔截過濾Object.ownKey()對對象的屬性遍歷;

<script type="text/javascript">
 let person={"name":"張三","age":20,"height":180};
 var pro=new Proxy(person,{
     ownKeys:function (target) {
         return ["name","age"]
     }
 });
    console.log(Object.keys(person));// ["name", "age", "height"]
    console.log(Object.keys(pro));// ["name", "age"]
</script>

has()攔截操作:攔截 key in object的操作,結果返回一個布爾值;用於判斷是否含有指定的鍵值對,有就返回true,否則返回false;

<script type="text/javascript">
 let person={"name":"張三","age":20,"height":180};
 var pro=new Proxy(person,{
     has:function (target,prop) {
         if(target[prop]===undefined){
             return false;
         }else {
             return true;
         }
     }
 });
    console.log("name" in person);           //true
    console.log("body" in person);          // false
</script>

apply()方法:被代理的變量是函數;

<script type="text/javascript">
 let fn=function () {
     alert("我是小王");
 };
 let proxy=new Proxy(fn,{
     apply:function () {
         alert("我不是小王")
     }
 });
    proxy();
</script>

Proxy.revocable()取消代理函數:返回一個對象,對象中含有一個Proxy的代理實例對象,還有一個revoke屬性,是一個方法,用於取消代理;

 <script type="text/javascript">
 let person={"name":"張三"};
 let handle={
     get:function (target,prop) {
         return "李四";
     }
 };
 let object=Proxy.revocable(person,handle); 
console.log(object.proxy.name);   //李四
object.revoke();
 console.log(object.proxy.name);   //報錯
 </script>

其他攔截操作

defineProperty( )   deleteProperty( )    enumerate( )
getOwnPropertyDescriptor( ) getPrototypeOf( )  isExtensible( )   preventExtensions( )  setPrototypeOf( )

12. 新特性for...of

for...of一種用於遍歷數組結構的方法,可遍歷對象包括數組,對象,字符串,set和map結構等具有iterator接口的數據結構;

for...of優勢:

(1)寫法比for循環簡潔很多;
2)可以用break來終止整個循環,或者continute來跳出當前循環,繼續後面的循環;
3)結合keys( )獲取到循環的索引,並且是數字類型,而不是字符串類型。

循環可以終止:

<script type="text/javascript">
var arr=[1,2,3,4,5];
for(let value of arr){
    if (value == 3){
        break;
    }
    console.log(value);      //1 2
}
 </script>

跳過當前循環:

 <script type="text/javascript">
var arr=[1,2,3,4,5];
for(let value of arr){
    if (value == 3){
        continue;
    }
    console.log(value);      //1 2 4 5
}
 </script>

得到數字類型索引:

 <script type="text/javascript">
var arr=[1,2,3,4,5];
for(let index of arr.keys()){
    console.log(index);        //0 1 2 3 4
    }
 </script>

遍歷字符串:

 <script type="text/javascript">
let word="我是前端君";
 for(let w of word){
     console.log(w);        //我 是 前 端 君
     }
  </script>

遍歷DOM.List:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
    let Plist=document.getElementsByTagName("p");
    for (let p of Plist)
        console.log(p);          //</script>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
</body>

13. ES6的Iterator遍歷器(迭代器)

for...of 不能遍歷Object對象:沒有內置遍歷器Iterator

Iterator遍歷器原理:當可遍歷對象被for...of遍歷的時候,[Symbol.iterator]()會被調用,返回一個iterator對象;其中還有一個很重要的方法:next():done的值爲false表示循環沒有結束,繼續遍歷,done的值爲true表示遍歷結束;

<script type="text/javascript">
    let arr=['a','b','c'];
    let iter=arr[Symbol.iterator]();
    console.log(iter.next());  //{value: "a", done: false}
    console.log(iter.next());  //{value: "b", done: false}
    console.log(iter.next());  //{value: "c", done: false}
    console.log(iter.next());    //{value: undefined, done: true}
</script>

for...of原理:先遍歷可遍歷對象的[Symbol.iterator]()方法,得到一個Iterator遍歷器對象,然後在遍歷器上不斷調用next()方法,直到done的值爲true的時候,就表示遍歷完成結束了;

自定義Iteration遍歷器

Object對象加一個[Symbol.iterator]()方法,把一個不可遍歷的Object對象,變成可遍歷的對象:

 <script type="text/javascript">
    let obj={
        0:"我是0",
        1:"我是1",
        2:"我是2",
        length:3,
        [Symbol.iterator]:function () {
            let _this=this;
            let index=0;
            return{
                next:()=>{
                    let value=_this[index];
                    let done=(index>=_this.length);
                        index++;
                        return {value,done}
                }
            }
        }
    };
    for(let v of obj){
        console.log(v);  // 我是0 我是1 我是2
    }
</script>

14. 特殊函數:Generator函數

Generator函數又叫生成器函數,是ES6重要的特性;

1)普通函數用function來聲明,Generator函數用function*聲明。

2)Generator函數內部有新的關鍵字:yield,普通函數沒有。

可以把Generator函數被調用後得到的生成器理解成一個遍歷器iterator,用於遍歷函數內部的狀態。

<script type="text/javascript">
   function* Hello(name) {
       yield `hello ${name}`;
       yield `how are you`;
       yield `bye`;
   }
   let ite=Hello('前端君')
   console.log(Hello('前端君')); //Hello {<suspended>}
   console.log(ite.next());//{value: "hello 前端君", done: false}
   console.log(ite.next());//{value: "how are you", done: false}
   console.log(ite.next());//{value: "bye", done: false}
   console.log(ite.next());//{value: undefined, done: true}
</script>

Generator函數的行爲:

Generator函數被調用後並不會一直執行到最後,它是先回返回一個生成器對象,然後hold住不動,等到生成器對象的next( )方法被調用後,函數纔會繼續執行,直到遇到關鍵字yield後,又會停止執行,並返回一個Object對象,然後繼續等待,直到next( )再一次被調用的時候,纔會繼續接着往下執行,直到done的值爲true。

yield語句作用:

相當於暫停執行並且返回信息。有點像傳統函數的return的作用,但不同的是普通函數只能return一次,但是Generator函數可以有很多個yield。而return代表的是終止執行,yield代表的是暫停執行,後續通過調用生成器的next( )方法,可以恢復執行。

next()方法接受參數:next()的參數會作爲上一個yield的返回值 ;

關鍵詞yield* :調用另一個Generator函數,用到關鍵詞yield*;

yield* gen1();
yield* gen2();

注意:如果一個Generator函數A執行過程中,進入(調用)了另一個Generator函數B,那麼會一直等到Generator函數B全部執行完畢後,纔會返回Generator函數A繼續執行。

Generator函數的用途:

用途:可以控制函數的內部狀態,依次遍歷每個狀態;可以根據需要,輕鬆地讓函數暫停執行或者繼續執行。

根據這個特點,我們可以利用Generator函數來實現異步操作的效果。

 原理是:利用Generator函數暫停執行的作用,可以將異步操作的語句寫到yield後面,通過執行next方法進行回調。

15. Set結構和Weakset

Set結構:新的數據結構,理解爲值的集合;它的值不會有重複項;Set本身是一個構造函數,可以理解爲一個類;

 <script type="text/javascript">
 var s=new Set([1,2,3]);
 console.log(s);

var v=new Set();
v.add(1);
v.add(2);
</script>

成員值唯一:添加相同的成員值會自動忽略相同的值,只會保留一個相同的值;

size屬性:獲取成員個數  

delete()方法:用戶刪除Set結構中的指定值,刪除成功返回:true,刪除失敗返回:fasle;

clear()清除所有成員;

has()方法:判斷set結構中是否含有指定的值;

entries()方法:返回一個鍵值對的遍歷器;Set結構是鍵名和鍵值是同一個值;

keys():返回鍵名的遍歷器;

values():返回鍵值的遍歷器;

forEach( )方法:遍歷每一個成員。

Set用途之一:給數組去重;

 <script type="text/javascript">
  let arr=[1,2,2,3,3,3,4,4];
  let s=new Set(arr);
    console.log(s);           //{1,2,3,4}
  let newArr=Array.from(s);
    console.log(newArr);      //[1,2,3,4]
</script>

WeakSet結構:同樣不會存儲重複的值,不同的是,它的成員必須是對象類型的值。(嚴格來說是:具有 iterable 接口的對象)

相同:WeakSet結構也提供了add( ) 方法,delete( ) 方法,has( )方法給開發者使用,作用與用法跟Set結構完全一致。
另一個不同點是:WeakSet 結構不可遍歷。因爲它的成員都是對象的弱引用,隨時被回收機制回收,成員消失。所以WeakSet 結構不會有keys( ),values( ),entries( ),forEach( )等方法和size屬性。

16. Map和WeakMap

Map基本用法:key鍵名的類型不再侷限於字符串類型,可以是各種類型是值;

<script type="text/javascript">
    let m = new Map([["name","前端君"],["gender",1]]);
    console.log(m);
</script>

 

set()方法作用:給實例設置一對鍵值對,返回Map實例;如果設置一個已經存在的鍵名,後面是鍵值會覆蓋前面的鍵值;

get()方法作用:獲取指定鍵名的鍵值,返回鍵值;不存在返回undefined;

delete()方法作用:刪除指定的鍵值對,刪除成功返回:true,否則返回:false;

clear()方法:一次刪除完所有鍵值對;

has()方法作用:判斷Map實例內是否含有指定鍵值對,有就返回true,否則返回false;

可遍歷:可以使用ES6新特性for...of遍歷鍵名或鍵值;

entries()方法:返回實例的鍵值對遍歷器;

keys()方法:返回實例所有鍵名的遍歷器;

values()方法:返回實例所有鍵值的遍歷器;

forEach()方法:遍歷每個鍵值對;

size屬性:獲取實例的成員數;

WeakMap()結構:鍵名支持引用類型的數據;(數組,對象,函數)

Map()結構不同點:

1)如果是普通的值類型則不允許。比如:字符串,數字,null,undefined,布爾類型。而Map結構是允許的,這就是兩者的不同之處,謹記。

2)跟Map一樣,WeakMap也擁有get、has、delete方法,用法和用途都一樣。不同地方在於,WeakMap不支持clear方法,不支持遍歷,也就沒有了keys、values、entries、forEach這4個方法,也沒有屬性size。

3)理由跟WeakSet結構一樣:鍵名中的引用類型是弱引用,你永遠不知道這個引用對象什麼時候會被垃圾回收機制回收了,如果這個引用類型的值被垃圾機制回收了,WeakMap實例中的對應鍵值對也會消失;

17.全新特性 Promise: 更合理,更規範處理異步操作;

Promise對象有三種狀態:

pending:剛剛創建一個Promise實例的時候,表示初始狀態;

fulfilled:resolve方法調用的時候,表示操作成功;

rejected:reject方法調用的時候,表示操作失敗;

注意:狀態只能從 初始化 -> 成功  或者  初始化 -> 失敗,不能逆向轉換,也不能在成功fulfilled 和失敗rejected之間轉換;

<script type="text/javascript">
    let pro=new Promise(function (resolve,reject) {   //實例後狀態:pending
        if("操作成功"){
            resolve();   //狀態爲:fulfilled
        }else {
            reject();//狀態爲:rejected
        }
    });
</script>

then()方法:用於綁定處理操作後的處理程序

pro.then(function (res) {
    //操作成功的處理程序
    
},function (error) {
    //操作失敗是處理程序
});

catch()方法:只接受一個參數處理操作異常後的業務;

綜合兩個方法:將then方法用於處理操作成功,catch方法用於處理操作異常;(之所以能鏈式調用,是因爲then方法和catch方法調用,都會返回promise對象)

pro.then(function (res) {
    //操作成功的處理程序

}).catch(function (error) {
    //操作失敗的處理程序
})

完整案例:

<script type="text/javascript">
    let pro=new Promise(function (resolve,reject) {   //實例後狀態:pending
        if(true){
            resolve("操作成功");   //狀態爲:fulfilled
        }else {
            reject("操作失敗");//狀態爲:rejected
        }
    });
    pro.then(requestA).then(requestB).then(requestC).catch(requestError);
    function requestA() {
        console.log("請求A成功");
        return '請求B,下一個就是你了';

    }
    function requestB(res) {
        console.log("上一步的結果"+res);
        console.log("請求B成功");
        return '請求C,下一個就是你了';

    }
    function requestC(res) {
        console.log("上一步的結果"+res);
        console.log("請求C成功");
    }
    function requestError(res) {
        console.log("請求失敗");
    }
    //打印結果:
    //請求A成功
    //上一步的結果:請求B,下一個就是你了
    //請求B成功
    //上一步的結果:請求C,下一個就是你了
    //請求C成功
</script>

 

 

 

Promise.all()方法:接受一個數組作爲參數,數組的元素是Promise實例對象,當參數中實例對象的狀態都爲fulfilled時,Promise.all()纔會返回;

<script type="text/javascript">
   let pro1=new Promise(function (resolve,reject) {
      setTimeout(function () {
          resolve('實例1操作成功');
          
      },4000);
   });
   let pro2=new Promise(function (resolve,reject) {
       setTimeout(function () {
           resolve('實例1操作成功');

       },2000);
   })
    Promise.all([pro1,pro2]).then(function (result) {
        console.log(result);    //延遲五秒輸出結果
    })
</script>

Promise.race()方法:只要有一個狀態發生變化,就會返回,不管是成功還是失敗;

18.類的概念

基本用法:constructor構造方法是一個類必須要有的方法;

類的屬性和方法和創建實例對象:必須使用new創建來創建;先聲明定義,再創建實例,否則會報錯;

  <script type="text/javascript">
       class Animal{
           constructor(name){   //constructor構造方法,不能含有多個constructor構造函數
               this.name=name;   //name屬性
           }
           getName(){          //自定義方法
               return 'This is a'+this.name;
           }
       }
       let dog=new  Animal('dog');    // 創建實例對象
       console.log(dog.name);    //dog
       console.log(dog.getName); //This is adog
</script>

類的靜態方法:直接使用類名即可訪問的方法;而實例方法通過實例對象來調用;

 <script type="text/javascript">
       class Animal{
           constructor(name){   //constructor構造方法,不能含有多個constructor構造函數
               this.name=name;   //name屬性
           }
           static friends(a1,a2){
               return `${a1.name} and ${a2.name} are friends`
           }
       }

       //創建實例
       let dog=new  Animal('dog');    // 創建實例對象
       let cat=new Animal('cat');
       //調用靜態方法;
       console.log(Animal.friends(dog,cat)); //dog and cat are friends
</script>

類的繼承:關鍵詞:extends實現子類繼承父類;

super:父類中的this

<script type="text/javascript">
       class Animal{}  //父類
       class Dog extends  Animal {
           constructor(name, color) {
               super(name);       //super:父類中的this
               this.color = color;
           }
       }
</script>

  使用super有幾個要注意的事項:

1)子類必須在constructor方法中調用super方法;

2)必須先調用super( ),纔可以使用this,否則報錯;super( )相當於父類構造函數的調用;

    <script type="text/javascript">
       class Animal{
           constructor(name){
               this.name=name;
           }
           say(){
               return `This is a animal`;
           }
       }
       //子類
       class Dog extends  Animal {
           constructor(name, color) {
               super(name);       //super:父類中的this
               this.color = color;
           }
           //子類實例方法
           getAttritube(){
               return `${super.say()},
               name:${this.name},
               color:${this.color}`;
           }
       }

       let d=new Dog("dog","black"); //創建Dog實例
       console.log(d.getAttritube()); //調用子類實例
       //This is a animal, name:dog, color:black
</script>

19. 缺失已久的特性:module模塊;

目前還沒有瀏覽器支持ES6的module模塊;

module模塊:一個模塊,就是一個對其他模塊暴露自己的屬性或者方法的文件;

導出Export:作爲一個模塊,可以選擇性的給其他模塊暴露(提供)自己的屬性和方法,供其他模塊使用;


//---module-B.js文件---
//導出變量:name
export var name = "前端君";

 

導入Import:作爲一個模塊,引入給其他模塊提供的屬性和方法,供自己模塊使用;

//---module-A.js文件---
//導入 模塊B的屬性 name
import { name } from "./module-B.js";
console.log(name)
//打印結果:前端君

批量導出:

//屬性name
var name = "前端君";
//屬性age
var age  = 25;
//方法 say
var say = function(){
    console.log("say hello");
}
//批量導出
export {name,age,say}

批量導入:變量名字必須跟導出的一致才能準確獲取,位置順序無要求;

//---module-A.js文件---

//導入 模塊B的屬性 name
import { name,age,say } from "./module-B.js";

console.log(name)
//打印結果:前端君

console.log(age)
//打印結果:25

say()
//打印結果:say hello

使用關鍵字as,可以實現給變量name更換名字爲myname。

import { name as myname } from "./module-B.js";
console.log(myname)
//打印結果:前端君

 

整體導入:使用星號符*將模塊B提供的所有屬性和方法整體導入賦值給變量obj,我們可以點運算符來獲取它的屬性和方法。

//使用*實現整體導入
import * as obj from "./module-B.js";

默認導出:每個模塊支持我們導出一個沒有名字的變量,我們使用關鍵語句export default來實現;

export default function(){
    console.log("I am default Fn");
}

 我們使用export default關鍵字對外導出一個匿名函數,導入這個模塊的時候,可以爲這個匿名函數取任意的名字;(同樣是使用import關鍵字導入模塊B,但是這次不需要使用大括號{ }。我們使用新的名字:sayDefault來代替導入的匿名函數,最後調用一下,打印結果正是模塊B默認導出的匿名函數的執行效果。);

//取任意名字均可
import sayDefault from "./module-B.js";

sayDefault();
//結果:I am default Fn

注意事項:

(1)聲明的變量,對外都是隻讀;但是,如果導出對象是對象類型,就可以修改;

(2)導入不存在的變量,值爲undefined;不會拋出異常;

 

 

 

 

 

 

發佈了22 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章