複習 - es6語法

Heymar發表於2022-11-23

這幾天電腦有點問題,一直在弄,而且論文也逼近了也在時間弄那個 ,前面node有一個大專案,已經做完了,我現在是準備把上次複習斷下的繼續複習一直到這個專案,然後就開始vue了。

1.

首先是函式的一個進階,要明白函式也是物件,所以是可以透過new的方法來建立例項的。

然後是呼叫函式的三個方法:call可以改變this加呼叫、apply可以改變this但是傳的引數是陣列也可以呼叫、bind可以改變this傳的引數也跟第一個call一樣但是就是不會自己呼叫。

2.

今天的主打內容

閉包首先要知道嚴格模式,use srict放在區域性或者全域性作用域都可以,然後有哪些變化,變數必須宣告賦值啊、this普通函式為undefined啊、函式形參不能重名啊、函式生命必須在頂層啊等等、

高階函式:就是函式里面巢狀一個函式或者return為一個函式

然後就是閉包,什麼事閉包?

閉包就是一個能夠訪問函式區域性變數的函式,兩個注意點,一個是函式,一個是訪問區域性變數。

還是跟以前一樣傳一些我第二次做有些感想的案例吧,就不全部傳上來了。第一個是點選li列印索引號透過閉包來做

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <script>
        /* let ul = document.querySelector('ul')
        for(var i = 0; i < ul.children.length; i++) {
            ul.children[i].setAttribute('data-index',i)
            ul.children[i].onclick = function() {
                console.log(this.getAttribute('data-index'));
            }
        } */
        // 這裡我自己做了一下沒有用到閉包來完成,如果規定不能新增自己的屬性呢 
        // 這個時候你只能用i 但是當你一點選就列印出i的值那肯定是最後一個i退出迴圈的值,為什麼,因為這裡for是主棧道上的程式碼,會先執行完,
        // 才會去執行事件裡面的非同步任務也就是回撥函式,所以這裡可以先用一個立即執行函式,一執行到這個i就先把這個i儲存起來有幾個迴圈就有幾個立即執行函式,
        // 當你一點選就把函式里面存著的i給到他 兩個函式 兩個作用域 用到了區域性變數 所以閉包產生
        let ul = document.querySelector('ul')
        for(var i = 0; i < ul.children.length; i++) {
            /* ul.children[i].onclick = function() {
                console.log(i);
            } */
            (function(i) {
                ul.children[i].onclick = function() {
                console.log(i);
            }
            })(i)
        }
    </script>
</body>
</html>

然後是閉包算價格這個,看得出來還有點沒有完全吃透閉包的原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 叫車起步價13(3公里內),  之後每多一公里增加 5塊錢.  使用者輸入公里數就可以計算叫車價格
如果有擁堵情況,總價格多收取10塊錢擁堵費 -->
<script>
    function getMoney() {
        let total = 13
        let price = 0
        return {
            price : function(n) {
                // console.log(total, mile);
                if(n > 3) {
                    price = total + Math.ceil(n - 3) * 5
                } else {
                    price = total
                }
                return price
            },
            congestionPrice : function(n,congestion) {
                this.price(n)
                if (congestion) {
                    price += 10
                } else {
                    price = total
                }
                return price
            }
        }
    }
    console.log(getMoney().price(1));
    console.log(getMoney().congestionPrice(1,true));
    console.log(getMoney().price(4));
    console.log(getMoney().congestionPrice(4, true));
</script>
</body>
</html>

3.

遞迴

遞迴就是在函式內部在呼叫自身,類似於迴圈,透過return來結束。遞迴有幾個經典案例我覺得可以看一下,這次做還是熟練了好多

第一個求階乘

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 利用遞迴函式求1~n的階乘 1 * 2 * 3 * 4 * ..n
        function getResult(n)  {
            if (n == 1) {
                return 1
            }
            return n * getResult(n - 1)
        }
        console.log(getResult(3));
    </script>
</body>
</html>

然後斐波拉起亞數列

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /* 利用遞迴函式求斐波那契數列(兔子序列)  1、1、2、3、5、8、13、21...
// 使用者輸入一個數字 n 就可以求出 這個數字對應的兔子序列值
// 我們只需要知道使用者輸入的n 的前面兩項(n-1 n-2)就可以計算出n 對應的序列值 */
        function getResult(n) {
            if (n == 1 || n == 2) {
                return 1
            }
            return getResult(n - 1) + getResult(n - 2)
        }
        console.log(getResult(5));
    </script>
</body>
</html>

這個有一點問題,我明說我沒執行出來,但是我真的很想知道我錯在哪裡了,原理都擺在這裡是沒問題的,程式碼也沒問題,求大神指教

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*  我們想要做輸入id號,就可以返回的資料物件*/
        var data = [{
   id: 1,
   name: '家電',
   goods: [{
     id: 11,
     gname: '冰箱',
     goods: [{
       id: 111,
       gname: '海爾'
     }, {
       id: 112,
       gname: '美的'
     },

            ]

   }, {
     id: 12,
     gname: '洗衣機'
   }]
 }, {
   id: 2,
   name: '服飾'
}];
    var o = {}
    function getData(arr, id) {
        arr.forEach(function(item) {
            if (item.id == id) {
                o = item
                return o
            } else if(item.goods && item.goods.length > 0) {
                getData(item.goods, id)
            }
        })
    }
    console.log(getData(data, 1));
    console.log(getData(data, 11));
    </script>
</body>
</html>

說到了遞迴就順便說一下淺複製和深複製。

淺複製就是隻複製表面的一層,深層次的東西就複製引用,就是不管你改哪邊的資料,雙方都會受影響

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 淺複製只複製一層 更深層次只複製引用 也就是你改或者他改值雙方都受影響
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            }
        }
        var o = {}
        for (k in obj) {
            o[k] = obj[k]
        }
        console.log(o);
        console.log('------------------')
        // es6快速淺複製語法
        Object.assign(obj, o)
        console.log(o);
    </script>
</body>
</html>

然後就是深複製,深複製就是可以單獨開闢空間,各管各的,互不影響,深複製的函式用到了遞迴,這個還是要記一下的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 深複製就是更深層的資料 也會單獨開闢空間 比如陣列、函式等
    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        },
        color: ['pink', 'red']
    }
    let o = {}
    function getCopy(usedCopy, useCopy) {
        for (k in usedCopy) {
            if (usedCopy[k] instanceof Array) {
                useCopy[k] = []
                getCopy(usedCopy[k], useCopy[k])
            } else if (usedCopy[k] instanceof Object) {
                useCopy[k] = {}
                getCopy(usedCopy[k], useCopy[k])
            } else {
                useCopy[k] = usedCopy[k]
            }
        }
    }
    getCopy(obj, o)
    console.log(o);
    </script>
</body>
</html>

4.

接下來是正規表示式。

這個其實各種語法我就不多說了,參考mdn、菜鳥教程這些多得很,我說一下今天的案例有一個替換敏感字元嘛,正則裡面的規則是中文的話不用寫引號,直接寫進去就是,一個案例郵箱提取,說一下exec這個方法怎麼來多次呼叫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
        將字串'小明:大神麼麼噠,正好是我想要的,我的郵箱是xiaoming@qq.com小紅:我老公最愛看這個了,我想給他一個驚喜,麼麼麼噠,
        郵箱是xiaohong@sina.com我:好人一生平安,郵箱是wuyou@163.com'中所有的郵箱號碼提取出來
 */
// 注意 要使用exec進行多次匹配不僅正則要新增全域性匹配 而且還有用一個while迴圈
        let str = `小明:大神麼麼噠,正好是我想要的,我的郵箱是xiaoming@qq.com小紅:我老公最愛看這個了,我想給他一個驚喜,麼麼麼噠,
        郵箱是xiaohong@sina.com我:好人一生平安,郵箱是wuyou@163.com`
        let reg = /\w+@\w+.[a-zA-z]+/g
        var result = reg.exec(str)
        while(result!== null) {
            console.log(result[0]);
            result = reg.exec(str)
        }
    </script>
</body>
</html>

正則差不多就這樣了

5.

然後是一些es6語法:let、const、解構賦值、箭頭函式。

其實我一直搞不懂let這個塊級作用域到底是限制在哪裡,我感覺作用域範圍跟var一樣哪裡都可以用,所以我後面基本都用let宣告的變數。當然我這個是錯誤思想哈,我是想以後慢慢透過例項來了解。

然後剩餘引數也就是擴充套件運算子三個點,然後就是array新增的一些方法、form可以將維陣列或者物件轉為陣列,第二個引數可以迴圈對每一個進來的值做操作,arr.find可以找滿足第一個條件的值,沒有就返回undefined,引數也是寫item\然後對應的findindex就是找

滿足第一個條件的引數的下標,還有就是查詢陣列裡面有沒有包含這個值.includes

然後就是模板字串。

string頁新增了一些方法:str.strtwith endstith看這個字元有沒有在這個字串的開頭或結尾。

.repeat可以將字元創重複n次返回一個新陣列。

最後就是set資料結構因為跟陣列相似,透過new 裡面的引數可以傳陣列,又因為自身的沒有重複值的特點所以給陣列起到一個去重的操作

然後他的一個屬性.size可以檢視set資料結構有多少值

add方法連式程式設計的形式新增資料

delete方法刪除返回的是布林值

has檢視有無返回布林值

clear清空資料結構

最後set也可以用forEach進行一個遍歷操作

相關文章