Day20 - 如何实现call和apply、bind

简介: Day20 - 如何实现call和apply、bind

知识讲解


call、apply、bind的功能就是改变this的指向、只是三个函数的参数风格不太一样。


call函数实现


[function].call([this], [param]...),一句话概括:call() 将函数的 this 指定到 call() 的第一个参数值同时将剩余参数指定的情况下调用某个函数或方法。


用测试用例描述


it("测试call方法", () => {
    const { call } = require("../index");
    Function.prototype.myCall = call;
    const obj = { a: 1 };
    const f = function (...args) {
      return { context: this, args };
    };
    expect(f.myCall(obj, 1, 2)).toEqual({ context: { a: 1 }, args: [1, 2] });
  });


代码实现


exports.call = function (context, ...args) {
  // this 为调用方法 例:f.call this = f
  context.fn = this;
  const result = context.fn(...args);
  delete context.fn;
  return result;
};


讲解


  • f.myCall函数调用时,this上下文其实是f函数。


  • 需要的绑定的上下文用参数context传入


  • 其余参数使用展开语法表示


  • 首先将函数绑定到上下文对象中


  • 删除context上线文中的fn方法清理现场


  • 返回执行结果


apply的实现


call方法和apply方法类似,两者唯一不同的是,执行参数是是一个数组而不是多个参数

测试用例表示


it("测试apply方法", () => {
    const { apply } = require("../index");
    Function.prototype.myApply = apply;
    const obj = { a: 1 };
    const f = function (...args) {
      return { context: this, args };
    };
    expect(f.myApply(obj, [1, 2])).toEqual({ context: { a: 1 }, args: [1, 2] });
});


代码实现


由于变动非常小甚至可以直接调用call函数完成


exports.apply = function (context, args) {
    return this.call(context,...args)
};


正经代码是这样


exports.apply = function (context, args) { // 只需要变动一行 ...args => args
  // this 为调用方法 例:f.call this = f
  context.fn = this;
  const result = context.fn(...args);
  delete context.fn;
  return result;
};


bind函数


bind返回fun的拷贝,并指定了fun的this指向,保存了fun的参数。


测试用例表示


it("测试bind方法", () => {
    const { bind } = require("../index");
    Function.prototype.myBind = bind;
    const obj = { a: 1 };
    const f = function (...args) {
      return { context: this, args };
    };
    expect(f.bind(obj, 1, 2)(3, 4)).toEqual({
      context: { a: 1 },
      args: [1, 2, 3, 4],
    });
});


代码实现


exports.bind = function (context, ...args) {
  // this 为调用方法 例:f.call this = f
  const f = this;
  return function F() {
    return f.apply(context, [...args, ...arguments]);
  };
};


  • 实现一个工厂函数


  • 使用apply指向函数


  • 使用传入的context作为上下文


  • 将bind传入的执行参数与执行F()时传入的参数合并作为执行参数


网络异常,图片无法展示
|


面试攻略


这个就是一道经典的手写代码题。


相关文章
|
2月前
|
JavaScript 前端开发 开发者
call、bind、apply区别
【10月更文挑战第26天】`call`、`bind` 和 `apply` 方法在改变函数 `this` 指向和参数传递方面各有特点,开发者可以根据具体的需求和使用场景选择合适的方法来实现更灵活和高效的JavaScript编程。
37 1
|
3月前
|
前端开发 JavaScript
比较一下apply/call/bind ?
本文首发于微信公众号“前端徐徐”,详细介绍了 JavaScript 中 `apply`、`call` 和 `bind` 方法的概念、使用场景及手动实现。主要内容包括: - **apply**:使用数组作为参数调用函数,并指定 `this`。 - **call**:直接传递参数调用函数,并指定 `this`。 - **bind**:返回一个绑定了 `this` 和部分参数的新函数。 文章还对比了这三个方法的区别,并提供了手动实现的代码示例。
27 2
|
JavaScript 前端开发
面试官: call、apply和 bind有什么区别?
面试官: call、apply和 bind有什么区别?
|
8月前
call\apply\bind详解
call\apply\bind详解
39 0
bind、call、apply 区别
bind、call、apply 区别
85 0
call、apply、bind笔记
call、apply、bind笔记
68 0
|
JavaScript 前端开发
关于 this 指向、如何实现 new call apply bind 我所知道的
关于 this 指向、如何实现 new call apply bind 我所知道的
85 0
|
前端开发
前端学习案例1:apply,call,bind使用1
前端学习案例1:apply,call,bind使用1
92 0
前端学习案例1:apply,call,bind使用1
apply、bind和call
apply、bind和call
99 0

热门文章

最新文章

下一篇
开通oss服务