call() apply() bind()方法 以及实现bind()方法

ES5对函数拓展了bind方法

作用:为函数绑定作用域(当函数执行的时候,改变函数的作用域,并传递参数)

目前为止改变作用域的方法|关键字: bind, call, apply, with, eval

call与apply的区别

他们都是改变函数作用域的方法,都是在调用该方法的时候,执行函数并改变作用域的,第一个参数都是改变的作用域

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);

 

posted @ 2020-06-09 12:20  没有茅台喝啤酒也行  阅读(199)  评论(0编辑  收藏  举报