likes
comments
collection
share

面试题解析:bind,call,apply的实现

作者站长头像
站长
· 阅读数 11

我们可以通过在Function的原型对象上添加方法来实现this指针上的bind,call,apply方法。需要注意的是,bind 方法会创建一个新的函数,并将指定的对象设置为新函数的上下文(即 this 的值),但并不立即调用该函数。而call和apply则是立即直接调用。

bind的实现

Function.prototype.mybind = function (context) {
    var fn = this;  // 保存原始函数的引用
    var args = Array.prototype.slice.call(arguments, 1);  // 获取除第一个参数外的其他参数

    return function() {
        var newArgs = args.concat(Array.prototype.slice.call(arguments));  // 将绑定时的参数和调用时的参数合并
        return fn.apply(context, newArgs);  // 使用 apply 方法调用原始函数并设置上下文
      };
}

function greet(message) {
    console.log(message + this.name);
  }
  
  var obj = { name: '张三' };
  var boundFunc = greet.mybind(obj, '姓名:');
  boundFunc();  // 输出:姓名:张三

在这个示例中,我们给 Function 的原型对象添加了一个 mybind 方法,以实现自定义的 bind 函数。定义了一个 greet 函数,然后使用 mybind 方法将其与 obj 上下文绑定,并传递 '姓名' 参数给 greet 函数。

call的实现

Function.prototype.mycall = function(context) {
    context = context || window; // 如果未提供上下文,则默认为全局对象
    context.ID = this; // 将当前函数设置为上下文对象的一个属性
    // 获取传入的参数
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
      args.push('arguments[' + i + ']');
    }
    // 调用函数
    var result = eval('context.ID(' + args + ')');
    // 清除添加的属性
    delete context.ID;
    return result;
  };

  function greet(greeting) {
    console.log(greeting + ':' + this.name);
  }
  
  var obj = { name: '张三' };
  greet.mycall(obj, '姓名');  // 输出结果-- 姓名:张三

在这个示例中,我们给 Function 的原型对象添加了一个 mycall 方法,以实现自定义的 call 函数。定义了一个 greet 函数,然后使用 mycall 方法将其与 obj 上下文绑定,并传递 '姓名' 参数给 greet 函数。

apply的实现

Function.prototype.myapply = function(context, argsArray) {
    context = context || window; // 如果未提供上下文,则默认为全局对象
    context.ID = this; // 将当前函数设置为上下文对象的一个属性
  
    // 构建参数列表字符串
    var args = [];
    for (var i = 0; i < argsArray.length; i++) {
      args.push('argsArray[' + i + ']');
    }
  
    // 调用函数
    var result = eval('context.ID(' + args + ')');
  
    // 清除添加的属性
    delete context.ID;
  
    return result;
  };

  function greet(greeting, punctuation) {
    console.log(greeting + ': ' + this.name + punctuation);
  }
  
  var obj = { name: '张三' };
  greet.myapply(obj, ['姓名',' 年龄:18']);  // 输出结果为——姓名: 张三 年龄:18

在这个示例中,我们给 Function 的原型对象添加了一个 myapply 方法,以实现自定义的 apply 函数。定义了一个 greet 函数,然后使用 myapply 方法将其与 obj 上下文绑定,并传递 '姓名' 参数给 greet 函数。

总结

  • 不传⼊第⼀个参数,那么默认为 window。
  • 这些方法在调用时,传入的第一个参数为要绑定的上下文,后续参数为要传递给原始函数的参数。
转载自:https://juejin.cn/post/7337631207024345127
评论
请登录