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>