关于js的软绑定

922 阅读1分钟

为什么有软绑定和硬绑定的区别

如果传递null或者undefined作为call,apply,或bind的this绑定参数,那么这些值会被忽略掉,取而代之的是默认绑定规则将适用于这个调用。 硬绑定会让this指向永远不变,失去了this的灵活性,如下:

var func = function () { console.log(this) }
var funcA = func.bind({})

funcA() // Object {}
funcA.call({a: 1}) // Object {} call无法再改变this指向

使用软绑定成功改变this指向:

var func = function () { console.log(this) }
var funcA = func.softBind({})

funcA() // Object {}
funcA.call({a: 1}) // Object {a: 1}

如何实现软绑定,《你不知道的JavaScript 上》中的软绑定的代码实现:

if(!Function.prototype.softBind){
    Function.prototype.softBind=function(obj){
        var fn=this;
        var args=Array.prototype.slice.call(arguments,1);
        var bound=function(){
            return fn.apply(
                (!this||this===(window||global))?obj:this,
                args.concat.apply(args,arguments)
            );
        };
        bound.prototype=Object.create(fn.prototype);//继承
        return bound;
    };
}

var args=Array.prototype.slice.call(arguments,1);这句其实是为了函数柯里化,也就是说,允许在软绑定的时候,事先传一些参数,在调用函数的时候再传入另一些参数