bind()函數與柯里化

bind()函數與柯里化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>bind()函數與柯里化</title>
</head>

<body>
    <script>
        // biad()函數
        // 與call()、apply()一樣,bind()函數可以指定函數執行時this綁定的對象
        // bind()方法創建一個新函數,在bind()被調用時,這個新函數的this被指定爲bind()的第一個參數,其餘參數將作爲新函數的參數,供調用時使用

        // 空對象(比{}更空)
        var ø = Object.create(null);
        var o = {
            name: "xxx"
        }
        var o2 = {
            name: "yyy"
        }
        function print() {
            console.log(this.name);
        }
        var newPrint = print.bind(o);
        newPrint();

        // bind函數最簡單的用法是創建一個新函數,不管怎麼調用,這個函數都有同樣的this值 
        // javascript中新手很容易犯的一個錯誤是將一個對象的方法拿出來調用,並期望方法中的this是原來的對象(比如在回調中傳入這個方法)
        // 如果不做特殊處理的話,一般會丟失原來的對象,基於這個,用原始的對象創建一個綁定函數,巧妙的解決了這個問題
        var x = 9;
        var module = {
            x: 10,
            getX: function () {
                console.log(this.x);
            }
        }
        // 直接取出調用:對象丟失
        var getX1 = module.getX;
        getX1();// 9
        // 使用bind創建新函數並綁定對象
        var getX = module.getX.bind(module);
        getX();// 10

        // Currying(柯里化),是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,
        // 並且返回接受餘下的參數而且返回結果的新函數的技術
        // 使一個函數擁有預設的初始參數,只要將這些參數作爲bind的參數寫在this的後面。
        // 當綁定函數被調用時,這些參數會被插入到目標函數的參數列表的開始位置,傳遞給綁定函數的參數會跟在他們後面

        function getArray() {
            return Array.prototype.slice.call(arguments);
        }

        console.log(getArray(1)); // [1]
        // 創建一個新函數並預設初始參數:
        var getArrayCopy = getArray.bind(ø, 2);
        console.log(getArrayCopy(3)); //[2,3]
        console.log(getArrayCopy(4)); //[2,4]


        // bind()可以對參數進行柯里化:
        function foo(a, b) {
            console.log("a:" + a + ",b:" + b);
        }

        // 第一個參數:
        // ø 調用bind()函數時作爲this傳遞給目標函數的值,
        // 如果使用new運算符構造綁定函數,則忽略該值
        // 當使用bind在setTimeout中創建一個函數作爲回調提供時,如果該參數爲原始值(基礎值)時都將隱式轉換爲object(裝箱操作)
        // 如果bind函數參數列表爲空,執行作用域的this將作爲新函數的this

        // 返回值:返回原函數的拷貝,並擁有指定的this值和初始參數
        var f = foo.bind(ø, 2);
        f(3);
        // 預設的初始參數存在時,新創建的函數中會忽略對應的參數 
        // 如果所有參數都被預設,則新函數中傳入的新的參數都會被忽略
        var f2 = foo.bind(ø, 3, 4);
        f2(5);






        // 實現一個add方法,使計算結果能夠滿足如下預期:
        // add(1)(2)(3) = 6;
        // add(1, 2, 3)(4) = 10;
        // add(1)(2)(3)(4)(5) = 15;

        // 實現思路:利用閉包存儲所有參數,在最後一次調用時相加
        function add(){
            // 存儲所有參數
            var args = Array.prototype.slice.call(arguments);

            var adder = function(){
                args.push(...arguments);
                return adder;
            }
            
            adder.toString = function(){
                return args.reduce(function(a,b){
                    return a + b;
                });
            }
            return adder;
        }
        console.log(+add(1)(2)(3));
        console.log(+add(1, 2, 3)(4));
        console.log(+add(1)(2)(3)(4)(5));
    </script>
</body>

</html>
發佈了20 篇原創文章 · 獲贊 10 · 訪問量 3469
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章