如何自己实现bind方法

由于在低版本浏览器没有js原生bind方法,所以要兼容低版本浏览器的话就要手动实现

了解bind函数

bind 强制将函数的执行环境绑定到目标作用域中去

与 call 和 apply 其实有点类似,但是不同点在于,bind 方法不会立即执行

“bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。”

if (!Function.prototype.bind) {
    Function.prototype.bind = function () {
        if(typeof this != 'function'){// 判断调用者是不是函数
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }
        var self = this,                        // 保存原函数 (this指向调用bind者)
        context = [].shift.call(arguments), // 把参数中的第一个剪切出来,保存需要绑定的this上下文
        args = [].slice.call(arguments);    // 剩余的参数转为数组
        return function () {                    // 返回一个新函数
            self.apply(context,[].concat.call(args, [].slice.call(arguments)));
        }
    }
}
复制代码

看到[].concat.call(args, [].slice.call(arguments)也有点蒙圈,参数不就是args么,为什么要合并它自己?如果你也是这么认为的那就请认真往下阅读 其实args是绑定上下文的时候(也就是bind())传递的参数,而后面的arguments则是调用bind()()第二个括号传递的参数,所以这里才会需要合并 如果还是有点不明白可以看看一下的代码 

Function.prototype.binding = function () {
    let self = this;
    let context = [].shift.call(arguments);
    let args = [].slice.call(arguments);
    console.log(args);
 
    return function () {
        self.apply(context, [].concat.call(args, [].slice.call(arguments)))
    }
};
 
let obj = {
    a: 'a'
};
 
function f(b, c, d) {
    console.log(this.a, b, c, d)
}
 
f.binding(obj, 'b', 'c', 'd')('e');
f.binding(obj, 'b', 'c')('d', 'e');
f.binding(obj, 'b')('c', 'd', 'e');
f.binding(obj)('b', 'c', 'd', 'e');
 
输出:
[ 'b', 'c', 'd' ]   a b c d
[ 'b', 'c' ]   a b c d
[ 'b' ]   a b c d
[] a b c d

上一篇:Can’t bind to ‘ngModel’ since it isn’t a known property of ‘nz-date-picker’.


下一篇:bind和apply以及call函数使用