ES5对函数拓展了bind方法
作用:为函数绑定作用域(当函数执行的时候,改变函数的作用域,并传递参数)
目前为止改变作用域的方法|关键字: bind, call, apply, with, eval
他们都是改变函数作用域的方法,都是在调用该方法的时候,执行函数并改变作用域的,第一个参数都是改变的作用域
call 从第二个参数开始,表示传递给函数的参数
apply 第二个参数是数组,每一个成员表示传递给函数的参数
bind跟call类似
第一个参数表示改变的作用域对象
从第二个参数开始,表示传递的参数
区别:
call | apply 调用即执行
bind调用不执行,但是得到一个新的方法,可以执行
bind方法实现也是通过apply实现的
bind通过两项技术实现的:
(1)函数绑定: 函数作为参数传递的同时,可以改变函数的作用域
作用:改变作用域
function demo() { console.log(arguments, this); } var obj = {}; // 函数的绑定:函数作为参数传递的同时,可以改变函数的作用域 function bind(fn, context) { // 返回一个新的函数 return function() { // 执行的时候,执行fn,并让this指向context return fn.apply(context, arguments); } } // 更改demo的this指向 var newDemo = bind(demo, obj); newDemo(1,2,3)
(2)函数柯理化:一个接收多个参数的函数,我们一个一个的传递参数,在函数执行的时候,传递剩余的参数并得到结果
function curry(fn) { // 从第二个参数开始,表示给函数传递的参数 var args = Array.prototype.slice.call(arguments, 1); // console.log(args) return function() { // 返回的函数接收剩余参数的,传递给fn去执行 // 将剩余的参数转成数组 var others = Array.prototype.slice.call(arguments, 0); // 返回fn执行的结果 return fn.apply(null, args.concat(others)) } } // 例如 我们传递一个参数 返回这个参数和curry中第二个参数的和 function add(num1, num2) { return num1 + num2; } var add10 = curry(add, 10); console.log(add10(4)); var add50 = curry(add, 50); console.log(add50(5));
作用:增强了函数的适用性
跟函数的重载有点像
函数的重载是在函数内部实现的
函数柯理化是在函数外部实现的(没有修改函数内部结构,类似于装饰者模式,是对函数的包装)
实现bind()方法
if(!Function.prototype.bind) { Function.prototype.bind = function(context) { // 备份this var t = this; // 获取传递的参数 var args = Array.prototype.slice.call(arguments, 1); console.log(args); // 返回一个新的方法 return function() { console.log(arguments); // 返回的函数中的参数是再次调动的函数传递的实参 // 参数就是执行时传递的参数 var others = Array.prototype.slice.call(arguments); console.log(others); // 执行方法并返回结果 return t.apply(context, args.concat(others)); } } } var res = demo.bind(obj, 1, 2, 3); res(4 , 5, 6);