apply & call & bind 源码

136 阅读1分钟

apply & call & bind 源码

  • call 源码
  • eval 是全局对象上的一个函数,会把传入的字符串当做 JavaScript 代码执行。如果传入的参数不是字符串,它会原封不动地将其返回
// call源码
Function.prototype.call = function(context) {
    // 获取上下文中的参数
    var context = context || window;
    // 保存当前上下文
    context.fn = this;

    // 参数数组
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']');
    }
    // 执行方法(es3语法) var result = context.fn(...args); // es6语法
    var result = eval('context.fn('+args+')');

    // 删除绑定的上下文属性
    delete context.fn;
    return result;
}
  • apply 源码
Function.prototype.apply = function(context, arr) {
    var context = Object(context) || window;
    // 将当前上下文对象保存
    context.fn = this;

    var result;
    if (!arr) { // 未传参数
        result = context.fn();
    } else {
        var args = [];
        for (var i = 0; i < arr.lenght; i++) {
            args.push('arr['+ i + ']');
        }
        result = eval('context.fn('+ args +')');
    }
    delete context.fn;
    return result;
}
  • bind源码
Function.prototype.bind = function (context) {
    
    var ctx = context;
    if (typeof ctx !== 'function') {
        throw new TypeError('Type Error!');
    }
    var self = this;
    function fn() {};
    // 继承调用者原型上的方法
    fn.prototype = this.prototype;
    var bound = function(args) {
        return self.apply(context, args || null);
    }
    bound.prototype = new fn();
    return bound;
}