前端面试题详解让前端飞

前端面试题:请你模拟实现bind函数

2018-11-27  本文已影响7人  mytac

查看github原文戳

Function.prototype.bind介绍

bindapplycall一样是创建某个新函数,其具有将上下文绑定到某函数上的功能,这个新函数被调用时,它内部的this指向被赋予的上下文。如:

var context = {
    name: 'mytac',
};

function original(a, b) {
    console.log(this.name)
    console.log('a', a)
    console.log('b', b)
}

var foo = original.bind(context, 1)
foo(2)
// mytac
// a 1
// b 2

模拟实现

我们需要在Function的原型链上创建函数,其参数要求和原生bind一样,包含一个上下文参数和多个传入该函数的实参。注意要将上下文this传入返回的匿名函数中,而不是在返回的匿名函数中获得上下文this,因为这时的匿名函数中this为调用该函数时的上下文,即Window。对于this概念比较模糊的小伙伴可以看我的这篇文章《一篇文章完全搞懂this》

Function.prototype.bindFn = function bind(thisArg) {
    if (typeof this !== 'function') {
        throw new TypeError(this + 'must be a function');
    }
    // 存储函数本身
    var self = this;
    // 去除thisArg的其他参数 转成数组
    var args = [].slice.call(arguments, 1);
    return function () {
        // bind返回的函数 的参数转成数组
        var boundArgs = [].slice.call(arguments);
        // apply修改this指向,把两个函数的参数合并传给self函数,并执行self函数,返回执行结果
        return self.apply(thisArg, args.concat(boundArgs));
    }
}

es6实现

使用es6就简单多了,尤其是对参数的处理上。...spread操作符可以将类数组转成数组,原理是...调用了类数组上的iterator。(这里可以看我的另一篇文章《ES6扫盲:用自定义iterator创建斐波那契数列》,会介绍iterator的神奇之处。)

Function.prototype.bindFn = function bind(ctx, ...args) {
    const self = this
    return function (...args2) {
        return self.apply(ctx, [...args, ...args2])
    }
}

参考链接

  1. MDN-Function.prototype.bind

最后请大家关注我的订阅号获得更加及时的推送~

那屋水泡
上一篇 下一篇

猜你喜欢

热点阅读