深度解析bind()方法及他的实现方法

bind()方法的解析

1.bind()方法是ECMAScript新增加的一个方法,主要作用是改变this指向。bind()是Function.prototype上的一个方法,所以调用它的只能是一个方法,bind会将调用它的方法里面的this指向bind()的第一个参数。

例如:

[].slice.bind([1,2,3,4],1)(2)
[].slice === Array.prototype.slice === new Array().slice
原本slice函数中的this应该指向[],而现在指向[1,2,3,4],实际上可以理解为`[1,2,3,4].slice(1,2)`
var sli = [].slice.bind([2, 3, 4, 5, 6], 1)(3)
        console.log(sli)    // Array[3, 4]

2.bind()方法的实现实际上是返回了一个函数体,函数体内的参数会与bind()方法第一个参数除外的其它参数合并为一个arguments并执行(都合并参数了,肯定是返回函数被调用了!!!)。

[].slice.bind([1,2,3,4],1)(2) == [].slice.bind([1,2,3,4], 1, 2)() == [].slice.bind([1,2,3,4])(1, 2)

function func(a, b, c) {
    console.log(a, b, c);
}

func.bind(null, 'linxin')('A', 'B', 'C');      // linxin A B
func.bind(null, 'linxin')('A', 'B', 'C') == windows.func('linxin', 'A', 'B', 'C') == func('linxin', 'A', 'B', 'C')

bind()方法的实现

IE老版本可能不支持 bind() 方法,所以可以写个兼容方法

if(!Function.prototype.bind) {
    Function.prototype.bind = function() {
       var self = this,      // 存储执行上下文
           context = [].shift.call(arguments),  // 获取bind()方法的第一个参数(因为 arguments 是一个类数组,并非真正的数组对象,它是没有Array原型上的方法的。shift() 方法会直接改变原始对象)
           args = [].slice.call(arguments); // 获取bind()方法剩下的参数
    return function() {
       self.apply(context, [].concat.call(args, [].slice.call(arguments)))
       //  self 保存了copyBind 的执行期上下文,所以这里的 self 指向的是copyBind而不是windows  
       //  [].concat.call(args, [].slice.call(arguments)) == args.concat([].slice.call(arguments))
        }
    }
}

“`

猜你喜欢

转载自blog.csdn.net/qq_42395080/article/details/82014927