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

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

bind的实现

javascript 复制代码
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的实现

javascript 复制代码
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的实现

ini 复制代码
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。
  • 这些方法在调用时,传入的第一个参数为要绑定的上下文,后续参数为要传递给原始函数的参数。
相关推荐
赖龙6 小时前
pnpm vs npm
前端·npm·node.js
To_OC7 小时前
LC 239 滑动窗口最大值:从暴力超时到单调队列一遍过
javascript·算法·leetcode
黄敬峰7 小时前
告别 Vibe Coding!SDD 规范驱动开发实战:从文档到代码的 AI 开发新范式
面试
学如逆水,不进则退7 小时前
在线免费音频剪辑:NBTools 可视化波形裁剪 MP3/WAV,本地处理免上传
前端·音视频
Mh7 小时前
虚拟滚动真的比普通滚动性能更好吗?
前端·javascript·性能优化
pe7er7 小时前
React + Ant Design 中的 IME (输入法合成)安全输入组件
前端
Super 含8 小时前
Android 启动优化(二):TTID、TTFD 与 Macrobenchmark 启动性能测量
前端
Python私教8 小时前
别急着加 llms.txt:企业官网面向 AI 搜索的工程清单
前端·人工智能·seo
东方小月8 小时前
从零开发一个 Coding Agent(十三):实现安全的 read 文件读取工具
前端·人工智能·全栈
东方小月9 小时前
从零开发一个 Coding Agent(十二):实现版本化 JSONL 与真实 CLI 入口
前端·设计模式·前端框架