callapplybind 的区别?call 和 apply 哪个性能会更好?如何实现 callapplybind?

Posted sfchris

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了callapplybind 的区别?call 和 apply 哪个性能会更好?如何实现 callapplybind?相关的知识,希望对你有一定的参考价值。

相同点

bind、apply、call 都是用来绑定函数执行时this的指向(改变函数执行时的上下文),同时还可以传参,调用它们的对象必须是一个函数 Function。

区别

区别主要提现在传参上。

// call
Function.call(obj, arg1, arg2, arg3, ...);

// apply,有两个参数,第二个是类数组
Function.apply(obj, [argArray]);

// bind,bind 方法的返回值是函数,需要手动调用才会执行,而 apply 和 call 则是立即调用
Function.bind(obj, arg1, arg2, arg3, ...);
const obj = {
  name: \'小鸭子\',
};

function say (arg1, arg2) {
  console.log(`${this.name ? `我是一只${this.name},` : \'\'}${arg1},${arg2}`);
}

say(\'咿呀咿呀哟\', \'呱呱!\'); // 咿呀咿呀哟,呱呱!

say.call(obj, \'咿呀咿呀哟\', \'呱呱!\') // 我是一只小鸭子,咿呀咿呀哟,呱呱!

say.apply(obj, [\'咿呀咿呀哟\', \'呱呱!\']); // 我是一只小鸭子,咿呀咿呀哟,呱呱!

const manualSay = say.bind(obj, \'咿呀咿呀哟\', \'呱呱!\'); // 绑定但不是立即执行
manualSay(); // 手动执行,输出:我是一只小鸭子,咿呀咿呀哟,呱呱!

性能比较

call 的性能要比 apply 好一些(尤其是传递给函数的参数超过三个的时候)

大概因为,apply 的第二个参数是数组,函数在执行时,解析数组获取参数,需要耗费性能。

call 实现

// call 实现
Function.prototype.myCall = function(context) {
  context = context || window; // 默认 window
  const args = [...arguments].slice(1); // 参数
  const fn = Symbol(); // 给 context 设置一个独一无二的属性,避免覆盖原有属性
  context[fn] = this; // 这里的 this 指向调用它的函数 fn
  const result = context[fn](...args); // 调用之
  delete context[fn]; // 删除添加的属性
  return result; // 返回值
}

say.myCall(obj, \'咿呀咿呀哟\', \'呱呱!\') // 我是一只小鸭子,咿呀咿呀哟,呱呱!

apply 实现

// apply 实现
Function.prototype.myApply = function(context, args) {
  context = context || window; // 默认 window
  args = [...args]; // 参数
  const fn = Symbol(); // 给 context 设置一个独一无二的属性,避免覆盖原有属性
  context[fn] = this; // 这里的 this 指向调用它的函数fn
  const result = context[fn](...args); // 调用之
  delete context[fn]; // 删除添加的属性
  return result; // 返回值
}

say.myApply(obj, [\'咿呀咿呀哟\', \'呱呱!\']) // 我是一只小鸭子,咿呀咿呀哟,呱呱! 

bind 实现

// bind 实现
Function.prototype.myBind = function(context) {
  context = context || window; // 默认 window
  const args = [...arguments].slice(1); // 参数
  const fn = this; // 这里的 this 指向调用它的函数 fn
  return function () {
    return fn.apply(context, args);
  };
}

const manualSay = say.myBind(obj, \'咿呀咿呀哟\', \'呱呱!\');
manualSay(); // 手动执行,输出:我是一只小鸭子,咿呀咿呀哟,呱呱! 

总结起来,call、apply、bind 的实现,要处理好以下几点:

  1. 绑定上下文 context
  2. 处理好参数 arguments
  3. 使用 Symbol 存储临时函数

后记

call、apply、bind 是 javascript 中非常重要的概念,也是前端面试中的高频面试题,无论是工作还是面试中,我们总是绕不开它,因此必须要掌握它,本文参考了许多网上大神的资料,文中若有不对之处,欢迎指正。本面试题收录在 leetoffer。

以上是关于callapplybind 的区别?call 和 apply 哪个性能会更好?如何实现 callapplybind?的主要内容,如果未能解决你的问题,请参考以下文章

使用callapplybind继承及三者区别

callapplybind不同使用场景

js中的callapplybind

理解JS中的callapplybind方法

理解JS中的callapplybind方法

理解JS中的callapplybind方法()