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>