面试题解析: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。
  • 这些方法在调用时,传入的第一个参数为要绑定的上下文,后续参数为要传递给原始函数的参数。
相关推荐
数研小生8 分钟前
亚马逊商品列表API详解
前端·数据库·python·pandas
你听得到1110 分钟前
我彻底搞懂了 SSE,原来流式响应效果还能这么玩的?(附 JS/Dart 双端实战)
前端·面试·github
不倒翁玩偶10 分钟前
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
前端·npm·node.js
奔跑的web.12 分钟前
UniApp 路由导航守
前端·javascript·uni-app
EchoEcho16 分钟前
记录overflow:hidden和scrollIntoView导致的页面问题
前端·css
Cache技术分享18 分钟前
318. Java Stream API - 深入理解 Java Stream 的中间 Collector —— mapping、filtering 和 fla
前端·后端
竟未曾年少轻狂21 分钟前
Vue3 生命周期钩子
前端·javascript·vue.js·前端框架·生命周期
TT哇26 分钟前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
蓝帆傲亦27 分钟前
Web前端跨浏览器兼容性完全指南:构建无缝用户体验的最佳实践
前端