面试题解析: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 分钟前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~10 分钟前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程15 分钟前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏17 分钟前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083161 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头2 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
wen's2 小时前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js
Alfred king2 小时前
面试150 生命游戏
leetcode·游戏·面试·数组
一只叫煤球的猫2 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
vvilkim2 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron