ES6 學習筆記

青檸i發表於2021-07-25

一、ECMAScript 6

1. Babel 轉碼器

1.1簡介

Babel 是一個廣泛使用的 ES6 轉碼器,可以將 ES6 程式碼轉為 ES5 程式碼

1.2babel 安裝和配置

1. 安裝babel
npm init -y 初始化package.json
npm i -D @babel/core
2. 安裝規則集
    npm i -D @babel/preset-env   // es6->es5的規則集
3. 建立配置檔案
    .babelrc檔案
    {
        "presets":[
            "@babel/env"
        ]
    }

1.3 命令列執行

1. 安裝命令列工具@babel/cli
    npm i -D @babel/cli
2. 語法
    npx babel target.js / -o buidle.js / -d dir

2.let

2.1 簡介

ES6 新增了let命令,用來宣告變數。它的用法類似於var,但是所宣告的變數,只在let命令所在的程式碼塊內有效

2.2 用法:

    let num = 12;

2.3 let塊級作用域

    在es6中,只有出現{},就會產生作用域,let宣告的變數如果在{}中,那麼這個變數就是區域性變數
    如果let宣告的變數出現在for迴圈中,這個變數也是區域性變數,只能在for迴圈的大括號中使用

2.4 不存在變數提升

console.log(str);
let str='';
//出現"Cannot access 'str' before initialization"報錯資訊,
//說明使用變數在前,宣告變數在後

2.5 不允許重複宣告

let str='';
let str='123';
//出現"Identifier 'str' has already been declared"報錯資訊,說明變數重複宣告瞭

2.6 暫時性死區

    var count = 1;
    {
        console.log(count);
        let count = 3;
    }
    //這時會報錯,報錯資訊是"先使用變數,後宣告變數"。

2.7 頂層物件的屬性

  • ES6 為了改變這一點,一方面規定,為了保持相容性,var命令和function命令宣告的全域性變數,依舊是頂層物件(window)的屬性;
  • 另一方面規定,let命令、const命令、class命令宣告的全域性變數,不屬於頂層物件(window)的屬性。

2.8 globalThis 物件

  • 全域性環境中,this會返回頂層物件。但是,Node 模組和 ES6 模組中,this返回的是當前模組。
  • 函式裡面的this,如果函式不是作為物件的方法執行,而是單純作為函式執行,this會指向頂層物件。但是,嚴格模式下,這時this會返回undefined

3. const

3.1 簡介

const宣告一個只讀的常量,一旦宣告,常量的值就不能改變。

3.2 用法

    const url = 'http://localhost:8080'

3.3 一旦宣告,常量的值就不能改變

const url='http';
const url='http://localhost:8080';//報錯
console.log(url);
//修改值時,會報錯:Assignment to constant variable

const obj={
    user:'fct'
}
obj.user='lllui';//不報錯
console.log(obj);
//如果常量儲存是一個物件,那麼這個常量其實只儲存了一個地址,和物件中的具體內容沒關係

3.4 let的幾個特點,const全都有

4. 變數的解構賦值

4.1 簡介

ES6 允許按照一定模式,從陣列和物件中提取值,對變數進行賦值,這被稱為解構(Destructuring)。

4.2 陣列解構賦值:

定義變數的結構和目標陣列的結構一致,那麼對應位置的變數就能獲取到對應位置的值。

// 1.陣列
let arr=[1,2,3,4];
let [b1,b2,b3]=arr;
console.log(b1,b2,b3);//1 2 3

let arr3 = [1,[2,3,[4,5,6,[7,8,9,[10]]]]];
// 3,5,9,10
let [,[,d1,[,d2,,[,,d3,[d4]]]]] = arr3
console.log(d1,d2,d3,d4);

// 2.陣列解構賦值--預設值
let [f=2]=[];
console.log(f);//2

/* 3. rest引數
    語法:[a1,...rest] = [1,2,3,4,5]
    作用:獲取匹配後剩餘的所有元素*/
let [a1,...rest] = [1,2,3,4,5];
console.log(a1,rest);//1 ,[ 2, 3, 4, 5 ]

4.3 物件的解構賦值:

定義變數名稱和物件中的屬性名一致,那麼就能獲取到對應屬性名的值。

// 1. 物件解構賦值-------------------------------
let obj={
    user:'fct',
    age:'21',
    sex:'sex'
}
let {age,sex,user,tel}=obj;
console.log(user,age,sex,tel);//fct 21 sex undefined

// 2. 解構也可以用於巢狀結構的物件
let obj2 = {
    info: {
        tel: '123',
        address: 'xx'
    }
};
//2.1 info是模式,不是變數因此不會被賦值
let { info: { tel, address }} = obj2;
console.log(tel, address);//123 xx
console.log(info);//info is not defined
//2.2 取info
let { info , info: { tel, address }} = obj2;
console.log(tel, address);//123 xx
console.log(info);//{ tel: '123', address: 'xx' }

//3. 修改變數名, uname:uname1---------(同名物件屬性)
let obj3 ={
    uname:'kevin',
    friends:{
        1:{
            uname:'lily'
        },
        2:{
            uname:'lucy'
        }
    }
};
// 3.1 修改friends變數名
let {friends:py}=obj3;
console.log(py);//{ '1': { uname: 'lily' }, '2': { uname: 'lucy' } }
// 3.2 模式,friends是模式
let {friends:{1:{uname}}}=obj3;
console.log(uname);//lily
// 3.3 想獲取lily和lucy兩個人名
let {uname:uname1,friends:{1:{uname:uname2},2:{uname}}} = obj3;

/* 修改變數名和匹配路徑上的模式的區別
    uname:uname1
    如果uname就是最終想獲取的值,uname1就是修改變數名;
    uname:{xxxxx} 
    如果uname是最終想獲取值的路徑上的名稱,uname就是模式*/

// 4.預設值
let { a = 2 } = {
    
};
console.log(a);//2

// 5. ...rest引數
let { a = 2, ...rest } = { a: 1, b: 2, c: 3 };
console.log(a, rest);//1 { b: 2, c: 3 }
//例題:解構物件賦值
let obj4 = {
    name: '電腦',
    main: [
        {
            name: '電源',
            pinpai: 'xx電源'
        }, {
            name: 'CPU',
            pinpai: 'YYCPU'
        }
    ],
    peijian: [
        {
            name: '鍵盤',
            pinpai: '羅技'
        }, {
            name: '滑鼠',
            pinpai: '雷蛇'
        }
    ]
}
// 取出所有的name的值
let {name:name1,main:[{name:name2},{name:name3}],peijian:[{name:name4},{name:name5}]}=obj4;
console.log(name1,name2,name3,name4,name5);//電腦 電源 CPU 鍵盤 滑鼠

4.4 函式的引數也可以使用解構賦值

//1. 形參解構賦值
function demo([a1,a2,a3,a4,a5]){
    console.log(a1,a2,a3,a4,a5);
}
demo([1,2,3,4,5]);//1 2 3 4 5

function demo2({a:first,b}){
    console.log(first,b);
}
demo2({a:1,b:2});//1 2

function demo3({a,...obj}){
    console.log(a,obj);
}
demo3({a:1,b:2,c:3});//1 { b: 2, c: 3 }

//2. 實參解構賦值
function demo4(a,b){
    console.log(a,b);
}
let obj={
    author:'fct',
    id:244,
    url:'http://',
    title:'標題',
    desc:'描述內容'
}
let {author,desc}=obj;
demo4(author,desc);//fct 描述內容

// 3.預設值
function demo5({ a = 5, b = 6 } = {}) {
    console.log(a, b);
}
demo5();//5 6
demo5({});//5 6
demo5({ a: 2 });//2 6

5. 字串擴充

5.1 模板字串

定義字串的新的方式,這種方式中可以隨意換行,可以寫變數,這個變數也可以直接被解析

//模板字串:
let obj={
    str1:'舉頭望明月,'
}
let str2='低頭思故鄉。'
let str=`
    床前明月光,
    疑是地上霜。
    ${obj.str1}
    ${str2}`;
console.log(str);
/*
    床前明月光,
    疑是地上霜。
    舉頭望明月,
    低頭思故鄉。
*/

6. 陣列擴充套件

6.1 擴充套件運算子

6.1.1 語法:

...arr

// 1.擴充套件運算子
let arr=[1,2,'a','b',true];
console.log(arr);//[ 1, 2, 'a', 'b', true ]
console.log(...arr);//1 2 a b true

6.1.2 作用:

​ 能把陣列中的元素直接釋放出來,成為一個個的值
6.1.3 應用場景:

  1. 替代函式的 apply 方法

    let arr=[1,2,'a','b',true];function demo(a,b,c,d,e){    console.log(a,b,c,d,e);}demo.apply(this,arr);//1 2 a b truedemo(...arr);//1 2 a b true
    
  2. 複製陣列 或 複製物件

    // 2.1複製陣列
    let arr2=[1,{name:'keli'},3];
    let arr3=[...arr2];
    arr2[1].name='lilei';
    arr2[0]=666;
    // 淺拷貝,地址引用還在
    console.log(arr2);//[ 666, { name: 'lilei' }, 3 ] 
    console.log(arr3);//[ 1, { name: 'lilei' }, 3 ]
    
    //2.2 複製物件
    let obj3={
        name:'fct',
        age:'22'
    }
    let obj4={...obj3};
    console.log(obj4);//{ name: 'fct', age: '22' }
    
  3. 合併陣列或物件

    //合併物件
    let obj={
        a:1,
        b:2,
        c:3
    }
    let obj2={
        d:4
    }
    obj2={...obj2,...obj};//合併物件
    console.log(obj2);//{ d: 4, a: 1, b: 2, c: 3 }
    
  4. 擴充套件運算子和rest引數有一個顯著的區別

    1.擴充套件運算子 永遠 出現等號的 右邊,或者直接使用。

    let obj4={...obj3};
    

    2.rest引數一般都在等號的左邊

    let { a , ...rest } = { a: 1, b: 2, c: 3 };
    console.log(a, rest);//1 { b: 2, c: 3 }
    
  5. 實現了 Iterator 介面的物件

    //將類陣列都可以用擴充套件運算子轉為真正的陣列let divList=document.querySelectorAll('div');let divArr=[...divList];//例2:function demo2(){    console.log(arguments);//[Arguments] { '0': 1, '1': 2, '2': 3, '3': 45 }    console.log([...arguments]);//[ 1, 2, 3, 45 ]}demo2(1,2,3,45);
    
  6. Map 和 Set 結構,Generator 函式
    原生具備 Iterator 介面的資料結構如下。
    Array
    Map
    Set
    String
    TypedArray
    函式的 arguments 物件
    NodeList 物件

6.2 Array.from()

Array.from(): 將類陣列轉化為真實的陣列

Array.from方法用於將兩類物件轉為真正的陣列:類似陣列的物件(array-like object)和可遍歷(iterable)的物件(包括 ES6 新增的資料結構 Set 和 Map)。

let obj5={
    0:'a',
    1:'b',
    2:'hello',
    length:3
}
// let arr4=[...obj5];//報錯,沒有部署Iterator介面
let arr4=Array.from(obj5);//成功
console.log(arr4);//[ 'a', 'b', 'hello' ]

6.3 Array.of()

用於將一組值,轉換為陣列

let arr5=Array.of(1,2,3,4);
console.log(arr5);//[ 1, 2, 3, 4 ]

let arr6=new Array(3);
console.log(arr6);//[ <3 empty items> ]

6.4 fill()

使用給定值,填充一個陣列

let arr7=new Array(5).fill(3);
console.log(arr7);//[ 3, 3, 3, 3, 3 ]

7.物件的擴充套件

7.1 屬性的簡潔表示法

ES6 允許在大括號裡面,直接寫入變數和函式,作為物件的屬性和方法

let x=10;
let obj={
    // x:x
    x,// 屬性簡潔表示法
    fn(a,b){//函式簡潔表示
        console.log(a,b);
    }
}
console.log(obj);//{ x: 10, fn: [Function: fn] }

7.2 屬性名錶達式

ES6 允許字面量定義物件時,把表示式放在方括號內,作為物件的屬性名

let str = 'uname';
function myage(){
    return 'age';
}
let obj3 ={
    [str]:'kevin',
    [myage()]:12
}
console.log(obj3);//{ uname: 'kevin', age: 12 }

7.3 物件新增的方法

1. Object.is()

在所有環境中,只要兩個值是一樣的,它們就應該相等
它用來比較兩個值是否嚴格相等,與嚴格比較運算子(===)的行為基本一致。
不同之處只有兩個:一是+0不等於-0,二是NaN等於自身。

Object.is('foo','foo');//true
Object.is({},{});//false

+-0===-0;//true
NaN===NaN;//false
Object.is(+0,-0);//false
Object.is(NaN,NaN);//true
2. Object.assign()

Object.assign方法用於物件的合併,將源物件(source)的所有可列舉屬性,複製到目標物件(target)

// Object.assign()
let target={};
let newObj=Object.assign(target,{a:1},{b:'cc',c:'er'},{d:4});
console.log(target);//{ a: 1, b: 'cc', c: 'er', d: 4 }
console.log(newObj);//{ a: 1, b: 'cc', c: 'er', d: 4 }

物件的每個屬性都有描述物件(Descriptor),用於控制該屬性的行為

Object.defineProperty( obj , key ,{
value : '值',
writable : true, //可寫
enumerable : true, //可列舉性
configurable : true // 是否可配置
})

0bject.assign():忽略enumerable為false的屬性,只拷貝物件自身的可列舉的屬性。

Object.getOwnPropertyDescriptor(obj,'key'),方法可以獲取該屬性的描述物件

3.Object.keys(),Object.values(),Object.entries()
  • Object.keys():獲取物件的鍵名
  • Object.values():獲取物件中的鍵值
  • Object.entries():成員是引數物件自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對陣列

8.Promise 期約

8.1 簡介

Promise 是非同步程式設計的一種解決方案,比傳統的解決方案——回撥函式和事件——更合理和更強大。

有了Promise物件,就可以將非同步操作以同步操作的流程表達出來,避免了層層巢狀的回撥函式。

所謂Promise,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。Promise 提供統一的 API,各種非同步操作都可以用同樣的方法進行處理。

8.2 使用

//Promise 是一個建構函式,使用時new
let p = new Promise(function(resolve,reject){
    // 非同步
    resolve(data) // 儲存請求成功時的結果
    reject(err)   // 儲存請求失敗是的錯誤資訊
});

//把Promise容器中儲存的結果拿出來
p.then(function success(data){

    },function error(err){

    })

8.3 網路請求工具

fetch (es6 內建的新的網路請求方式)

axios (ajax)

8.4Promise 三個狀態

1、pending--------[待定]--------------初始狀態
2、resolved------[實現]----------------操作成功
3、rejected-----[被否決]-------------操作失敗

當promise狀態發生改變,就會觸發then()裡的響應函式處理後續步驟;
promise狀態一經改變,不會再變。
Promise物件的狀態改變,只有兩種可能:
從pending變為resolved
從pending變為rejected。
這兩種情況只要發生,狀態就凝固了,不會再變了

8.5 Promise.proptotype.then()

  • then()方法返回的是一個新的Promise例項(注意,不是原來那個Promise例項)。因此可以採用鏈式寫法,即then方法後面再呼叫另一個then方法。

  • then()方法中如果沒有顯式的寫return,就會預設return undefined

  • then()方法中的return 後是一個具體的值,那麼promise會直接把這個結果儲存到成功狀態中

  • then()方法中return後自己寫new Promise,最終的狀態就和你寫的new Promise返回結果有關

8.6 Promise.prototype.catch()

.catch() = .then(null,function(err){})
//捕獲Promise錯誤的資訊

8.7 Promise.prototype.finally()

不管Promise是成功了還是失敗了,這個方法一定會執行

8.8 Promise.prototype.all()

  • Promise.all()方法用於將多個 Promise 例項,包裝成一個新的 Promise 例項

  • 語法:

    let p=Promise.all([p1,p2,p3]);
    p.then((data)=>{
      conlose.log(data);//輸出資料集合
    })
    
  • 返回值:

    1. 當p1,p2,p3都成功時,能獲取到這個三個promise的成功結果,組成一個陣列
    2. 當這三個promise有任意一個失敗,Promise.all就返回失敗結果

8.9 Promise.race()

  • Promise.race()方法同樣是將多個 Promise 例項,包裝成一個新的 Promise 例項,只要p1、p2、p3之中有一個例項率先改變狀態,p的狀態就跟著改變。

  • 語法:

    let first=Promise.race([p1,p2,p3]);
    first.then((data)=>{
      conlose.log(data);//獲取最先改變狀態的期約Promise
    })
    
  • 返回值:
    只要p1、p2、p3之中有一個例項率先改變狀態,p的狀態就跟著改變。

8.10 Promise.resolve()

​ 簡寫:resolve()

​ 把promise的狀態設定成功狀態

8.10 Promise.reject()

​ 把promise的狀態設定失敗狀態

8.11 Promise.allSettled()

  • 接受一組 Promise 例項作為引數,包裝成一個新的 Promise 例項。只有等到所有這些引數例項都返回結果,不管是fulfilled還是rejected,包裝例項才會結束。

  • 語法

    let results=Promise.allSettled([p1,p2,p3]);
    results.then((data)=>{
        console.log(data);//Promise資料陣列
    })
    

9.Generator(瞭解)

  • Generator 函式是 ES6 提供的一種非同步程式設計解決方案,語法上,首先可以把它理解成,Generator 函式是一個狀態機,封裝了多個內部狀態,執行 Generator 函式會返回一個遍歷器物件,可以依次遍歷 Generator 函式內部的每一個狀態.

  • 語法:
    Generator 函式是一個普通函式,但是有兩個特徵。一是,function關鍵字與函式名之間有一個星號;二是,函式體內部使用yield表示式,定義不同的內部狀態(yield在英語裡的意思就是“產出”)。

  • 執行Generator後返回值是遍歷器物件,這個物件上有一個方法next(),呼叫這個方法才能執行Generator 函式內部的每一個狀態.

  • next()方法的返回值
    next方法返回一個物件,它的value屬性就是當前yield表示式的值hello,done屬性的值false,表示遍歷還沒有結束

    //Generator 函式
    function* hello(){
        yield 'hello',
        yield 'world',
        yield 1;
        yield 2;
        yield 'fct';
    }
    let it=hello();//生成遍歷器物件
    
    console.log(it);//hello {<suspended>}
    console.log(it.next());//{value: "hello", done: false}
    console.log(it.next());//{value: "world", done: false}
    console.log(it.next());//{value: 1, done: false}
    console.log(it.next());//{value: 2, done: false}
    console.log(it.next());//{value: "fct", done: false}
    console.log(it.next());//{value: undefined, done: true}
    
  • co庫

快速執行Generator函式

10.Async 函式

10.1 簡介

​ 是 Generator 函式的語法糖(新語法), 理解async = Generator + co

await 也是狀態機,只有await後的程式碼執行完成,才能向後執行,await還能執行promise.then()方法

10.2 語法

//語法:
async function demo(){
    await 1;
    await 2;
}
//呼叫
demo();

10.3 使用

async function demo(){
    let a=await 1;
    let b=await 2;
    let c=await 'fct';
    return a+'-'+b+'-'+c;
}
console.log(demo());//Promise { <pending> }---返回值是Promise物件
demo().then((data)=>{
    console.log(data);//   1-2-fct
    // 無return ,值為  undefined
})

10.4 優點

  1. 內建執行器
  2. 更好的語義
  3. 更廣的適用性
  4. 返回值是 Promise

10. 5 錯誤捕獲

  • async函式返回一個 Promise 物件
  • Promise 物件的狀態變化:預設的,async函式返回的 Promise 物件,必須等到內部所有await命令後面的 Promise 物件執行完,才會發生狀態改變,除非遇到return語句或者丟擲錯誤。
  • 任何一個await語句後面的 Promise 物件變為reject狀態,那麼整個async函式都會中斷執行,則reject的引數會被catch方法的回撥函式接收到

10.6 await命令

  • 正常情況下,await命令後面是一個 Promise 物件,返回該物件的結果值。
  • 如果不是 Promise 物件,就直接返回對應的值。

11. 函式擴充套件

11.1 函式引數的預設值

// es6 函式引數預設值
function demo(a=1,b=3){
    console.log(a+b);
}
demo();//1+3=4
demo(2);//2+3=5
demo(4,6);//4+6=10

// 引數是陣列
function demo2([a=1,b=2]=[]){
    console.log(a+b);
}
demo2();//3
demo2([5]);//7
demo2([5,4]);//9

// 引數是物件
function demo3({a=3,b=6}={}){
    console.log(a+b);
}
demo3();//9
demo3({a:1});//7
demo3({b:2});//5
demo3({num1:1,num2:2});//9

11.2 rest引數

ES6 引入 rest 引數(形式為...變數名),用於獲取函式的多餘引數
注意:rest引數必須放在函式形參的最後一位

// rest引數function demo4(a,b,...abc){    console.log(abc);}demo4(1,2,3,4,5);//[ 3, 4, 5 ]

11.3 嚴格模式

​ ES2016 做了一點修改,規定只要函式引數使用了預設值、解構賦值、或者擴充套件運算子,那麼函式內部就不能顯式設定為嚴格模式,否則會報錯。

​ 一般把嚴格模式加在全域性。

11.4 name屬性

​ 函式的name屬性,返回該函式的函式名。

function demo(){}
demo.name //demo

11.5 箭頭函式

​ ES6 允許使用“箭頭”(=>)定義函式。

this引用的是定義箭頭函式的上下文

//語法:
  let demo = () => (123||{a:1},[1,2,3])
  //同上
  function demo(){
      return 123||{a:1},[1,2,3];
  }
  let demo = () => {console.log('沒有返回值的箭頭函式')}
  let demo = a => a;
  let demo = (a,b) => { return a+b};

使用注意點:
(1) 函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。

箭頭函式內部不自動產生this,而是使用定義箭頭函式時所在位置的外層作用域中的this

​ (2) 不可以當作建構函式

 (3)	不能用作 Generator 函式

​ (4) 不可以使用arguments物件,使用rest引數替代

12.class

12.1 基本使用

	ES6 的class可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的class寫法只是讓物件原型的寫法更加清晰、更像物件導向程式設計的語法而已。
//語法:
class Person{
    //構造方法:預設例項化時會自動呼叫,做初始化
    constructor(name,age,sex){
        this.name = name;
        this.age =age;
        this.sex = sex;
    }
    say(){
        console.log('我是',this.name);
    }
}
//使用
let obj = new Person('小明',12,'男');
console.log(obj);//Person { name: '小明', age: 12, sex: '男' }
obj.say();//我是 小明

12.2 說明:

  • 在class中定義的方法,是放在建構函式的原型上的

  • 類的內部所有定義的方法,都是不可列舉的

    conlose.log(Object.keys(Person.prototype));//[]
    console.log(Object.getOwnPropertyNames(Person.prototype));//[ 'constructor', 'say' ]
    
  • 一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被預設新增

  • 例項化class時,必須有new關鍵字,否則報錯

  • 取值函式(getter)和存值函式(setter)

    get getName(){
            return this.name;
        }
    set setName(value){
        this.name=value;
    }
    
    
    obj.setName='xiaoming';
    console.log(obj.getName);//xiaoming
    obj.say();//我是 xiaoming
    
  • this指向問題

    1. ES6 模組中,this返回的是當前模組

    2. 單純作為函式執行,this會指向頂層物件。但是,嚴格模式下,這時this會返回undefined

    3. 如果類中的一個函式不管是通過例項化物件呼叫還是作為純函式呼叫,我都想讓函式中的this指向當前類的例項(當前模組),處理方案有2種

      1. constructor方法中繫結this

         this.say = this.say.bind(this);
        
      2. 使用箭頭函式

        say =()=>{
            
        }
        
  • 靜態方法
    在一個方法前,加上static關鍵字,就表示該方法不會被例項繼承,而是直接通過類來呼叫,這就稱為“靜態方法”

    class Person{
      static all(){//定義靜態方法
    
      }
    }
    
    //使用:
    Person.all();
    //如果靜態方法包含this關鍵字,這個this指的是類
    
  • 繼承

    • Class 可以通過extends關鍵字實現繼承

      //語法
      class Bird{
          constructor(cb,leg) {
              this.cb=cb;
              this.leg=leg;
          }
          fly(){
              console.log('會飛');
          }
      }
      // 麻雀
      class Maqu extends Bird{
          constructor(cb,leg,name,color){
              super(cb,leg);//呼叫父類的constructor()
              this.name=name;
              this.color=color;
          }
          tiao(){
              console.log('用'+this.leg+'跳');
          }
      }
      let lily=new Maqu('2只翅膀','2條腿','lily','白色');
      console.log(lily);//Maqu { cb: '2只翅膀', leg: '2條腿', name: 'lily', color: '白色' }
      lily.fly();//會飛
      lily.tiao();//用2條腿跳
      
    • super()
      子類必須在constructor方法中呼叫super方法,否則新建例項時會報錯。這是因為子類自己的this物件,必須先通過父類的建構函式完成塑造,得到與父類同樣的例項屬性和方法,然後再對其進行加工,加上子類自己的例項屬性和方法。如果不呼叫super方法,子類就得不到this物件。

      //呼叫父類的constructor()
      super();
      

13.Es6 module

13.1 簡介

​ ES6 模組功能主要由兩個命令構成:exportimportexport命令用於規定模組的對外介面,import命令用於輸入其他模組提供的功能。

//export 匯出命令
//  13_moduleA.js
export var num=12;

export function demo(){
    console.log('demo');
}

export let count=10;

export const url='http://localhost:3000';

export class Person{
    constructor(name){
        this.name=name;
    }
}

export let jt=()=>{
    console.log('箭頭函式');
}

let num1=1;
let num2=2;
export{
    num1,num2
}

// 重新命名匯出的模組 可以使用as關鍵字重新命名
export { num as myNum};//將num重新命名為  myNum
//import 匯入命令
//13_moduleB.js
import {num,demo,count,url,Person,jt,num1,num2} from './13_moduleA.js';
//注意:引入的必須是xx.js中export匯出的資料
console.log(num);
demo();
console.log(count);
console.log(url);
let m=new Person('小明');
console.log(m);
jt();

//把xx.js中所有export匯出的資料取出來,然後放到obj物件上
import * as obj from './xx.js';

13.2export default 匯出命令

  //預設匯出,一個js中只能出現一次
  const pic='1.jpg';
  export default pic://匯出一個名稱為`default`的模組
  
  //import 匯入 export default模組語法:
  import A/b/myPic from './xx.js';//隨便命名
  • 使用webpack執行該專案
    安裝:

    npm i -S webpack webpack-cli webpack-dev-server
    npm i -g webpack webpack-cli webpack-dev-server
    

    建立一個配置檔案:webpack.config.js
    執行webpack命令,在code資料夾下執行
    webpack ,然後按Enter鍵
    在dist資料夾下建立一個index.html,在這個HTML中新增
    在執行一條命令:webpack-dev-server
    在瀏覽器中開啟 http://localhost:9000/

14.Proxy 代理

14.1 簡介

Proxy 可以理解成,在目標物件之前架設一層“攔截”,外界對該物件的訪問,都必須先通過這層攔截,Proxy 用於修改某些操作的預設行為。

14.2 使用

//語法:
  new Proxy(target,handler);
//返回值----返回一個物件

14.3 Proxy 支援的攔截操作有13個

  • get(target, propKey, receiver):攔截物件屬性的讀取

  • set(target, propKey, value, receiver):攔截物件屬性的設定

    等......

14.4 應用

let obj={
    name:'lilei',
    age:21,
    sex:'男'
}
let proxy=new Proxy(obj,{
    get(target,key,receiver){
        console.log(target,propKey,receiver);//{ name: 'lilei', age: 21, sex: '男' } name { name: 'lilei', age: 21, sex: '男' }
        // console.log('禁止訪問任何屬性');
        // return false;   //1. 
        return '結果:'+Reflect.get(target,key,receiver);//2.
    },
    set(target,propKey,value,receiver){
        console.log(target,propKey,value,receiver);
        //{ name: 'lilei', age: 21, sex: '男' } name 小明 { name: 'lilei', age: 21, sex: '男' }
        return Reflect.set(target,propKey,value,receiver);
    }
});

console.log(proxy.name);//1. false---- 2.結果:lilei
proxy.name='小明';
console.log(proxy.name);//結果:小明
  • 會使用到的一個API,Reflect

15. less

15.1 簡介

lesscss的預處理語言。除了less,還有scss(sass)stylus這些預處理語言。將CSS賦予了動態語言的特性,如 變數, 繼承, 運算, 函式。

css預處理語言編寫的css,瀏覽器是不認識,所以需要首先編譯成純css,需要使用工具。命令列工具 ,gulpwebpack

15.2 安裝

#安裝
npm install xxxxxxxx

#全域性安裝,全域性安裝後,主要就是給命令列提供命令的
npm i -g less

#專案依賴:就是給當前專案使用的
npm i -S / -D less
#-S 是 --save-dev 的簡寫,作用是開發階段和上線階段都需要使用的模組,預設值就是-S ,如:npm i less
#-D 是 --save 的簡寫,作用是隻在開發階段使用

15.3 使用

  • 建立less檔案
    首先建立一個.less結尾的檔案
  • 命令列編譯
    lessc xx.less xx.css

15.4 less語法

  1. 變數

    // 定義變數
    @danger:red;
    @baseWidth:20px;
    @baseHeight:10px;
    @warning:yellow;
    @success:green;
    @primary:blue;
    
    #box{
        min-height: @baseHeight*20;
        background: @warning;
        color:@danger;
    }
    
  2. 巢狀

    • 提供了使用巢狀(nesting)代替層疊或與層疊結合使用的能力

      #box{
          min-height: @baseHeight*20;
          background: @warning;
          color:@danger;
          // 巢狀
          .sp1{
              color:@primary;
              font-size:ceil(200/34px);
          }
      }
      
    • &妙用

      .font{
          color:#cccccc;
          font-size:20px;
          // &妙用:代表的上一層選擇器的名字
          &:hover{
              color:darken(@danger,20%);
          }
      }
      
  3. 混合

    • 宣告的集合,使用時 直接鍵入名稱即可

      // margin 集合.margin20{//無引數可省略(    margin:@baseWidth;}// 宣告圓角效果,1. 固定值.radius(){    border-radius: 4px;}// 2. 可變的值.radius2(@w){    border-radius: @w;}// 3. 變數可以有預設值.radius3(@w:5px){    border-radius: @w;}.c1 {    border:1px solid @success;    .margin20;    .radius();}.c2{    border:1px solid @danger;    .margin20;    .radius2(8px);}.c3{    border:2px solid @primary;    .margin20;    .radius3(10px);}
      
      1. 繼承
        可以實現css複用

        #box2{
            &:extend(#box);
            //&:extend(#box .p1 .font);
            //&:extend(#box all);
        }
        //all屬性,繼承整個目標的樣式,包括子級 
        
  4. 匯入
    允許在less檔案中引入其他的less或css檔案

    @import 'path';
    @import 'test.less';
    
  5. 函式
    都是內建的,直接使用就可以

    • 判斷型別
    • 顏色操作
    • 數學函式
  6. 迴圈方法

// 迴圈方法
.generate-columns(@n, @i: 1) when (@i =< @n) {
    .column-@{i} {
      width: (@i * 100% / @n);
      height: 10px;
      background:darken(@primary,@i * 5%);
    }
    .generate-columns(@n, (@i + 1));
}
.generate-columns(10);

相關文章