方法1

Funtion.prototype.bind = function(context){
    var self = this;
    return function(){
        return self.apply(context, arguments);
    }
}
  • 缺点: 没有办法在调用bind方法的时候指定额外的参数

方法2

Function.prototype.bind = function(context){
    var args = Array.prototype.slice.call(arguments, 1),
        self = this;
    return function(){
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = args.concat(innerArgs);
        return self.apply(context, finalArgs);
    }
}

方法3

在JavaScript中,使用bind方法会遇到以下这种情况:

function Person(){
    this.name = 'xin';
    this.age = '22';
}
var obj = { sex: 'male'};
var temp = Person.bind(obj);
temp();
// 调用temp后,obj就成为了
/*{
    name: 'xin',
    age: '22',
    sex: 'male'
}*
var p = new temp();
// 结果为: p = { name: 'xin', age: '22'}

通过上面的例子,可以看到通过new方式调用temp方法和用new方式调用Person方法的结果是一致的,那么这种情况该如何实现呢?下面的方法是《JavaScript Web Application》一书中对bind()的实现:通过设置一个中转构造函数F,使绑定后的函数与调用bind()的函数处于同一原型链上,用new操作符调用绑定后的函数,返回的对象也能正常使用instanceof,因此这是最严谨的bind()实现。

Funtion.prototype.bind = function(context){
    var args = Array.prototype.slice.call(arguments, 1),
        self = this,
        F = function(){},
        bound = function(){
            var innerArgs = Array.prototype.slice.call(arguments);
            var finalArgs = args.concat(innerArgs);
            // 当通过new方法调用时,this就是F的一个实例
            return self.apply((this instanceof F ? this: context), finalArgs);
        };
    F.prototype = self.prototype;
    bound.prototype = new F();
    return bound;
}

参考资料

Javascript中bind()方法的使用与实现


jhhfft
590 声望40 粉丝

Write the Code. Change the World.