前端 apply,call,bind作用及手写

1. 原理

apply()

  • 作用:apply 用于调用一个函数,并指定函数内部的 this 值以及传入的参数(参数必须是数组或者类数组对象)。
  • 语法:func.apply(thisArg, [argsArray])
  • thisArg:函数内的 this 指向的对象
  • argsArray:一个数组或类数组对象,包含传递给函数的参数。
  • 特点:apply 立即执行函数。参数传递的方式是数组或类数组。

call()

  • 作用:call 和 apply 很相似,也用于改变函数内部的 this,但是参数传递的方式不同。call 接收的参数是逐个传递的,而不是数组。
  • 语法:func.call(thisArg, arg1, arg2, ...)
  • thisArg:函数内的 this 指向的对象。
  • arg1, arg2, ...:逐个传递给函数的参数。
  • 特点:call 立即执行函数。参数逐个传递,而不是作为数组传递。

bind()

  • 作用:bind 创建一个新的函数,this 会绑定到指定的对象,并且可以选择性地传递参数。与 apply 和 call 不同,bind 不会立即执行函数,而是返回一个新的函数,可以在之后的某个时刻调用。
  • 语法:const newFunc = func.bind(thisArg, arg1, arg2, ...)
  • thisArg:新的 this 指向的对象。
  • arg1, arg2, ...:预先传递给新函数的参数。
  • 特点:bind 返回一个新的函数,并不会立即执行。可以预先传递一些参数,这些参数会被绑定在新函数中,后续调用时可以继续传入参数。
function showDetails(city, country) {
  console.log(`${this.name} lives in ${city}, ${country}.`);
}

const person = { name: 'John' };

// 使用 call
showDetails.call(person, 'New York', 'USA'); 
// John lives in New York, USA.

// 使用 apply
showDetails.apply(person, ['New York', 'USA']); 
// John lives in New York, USA.

// 使用 bind
const boundFunc = showDetails.bind(person, 'New York');
boundFunc('USA'); 
// John lives in New York, USA.

2. 手写实现

手写call()

Function.prototype.myCall = function (thisArg,...args){
  // 如果 thisArg 为 null 或 undefined,则指向全局对象
  thisArg = thisArg || globalThis;
  // 创建一个唯一的属性来避免覆盖已有的属性
  const uniqueKey = Symbol();
  thisArg[uniqueKey] = this;
  // 使用展开的 args 调用函数
  const result = thisArg[uniqueKey](...args);
   // 删除临时属性
  delete thisArg[uniqueKey];
  return result;
}

手写apply()

Function.prototype.myApply = function(thisArg, argsArray) {
  // 如果 thisArg 为 null 或 undefined,则指向全局对象
  thisArg = thisArg || globalThis;
  // 创建一个唯一的属性来避免覆盖已有的属性
  const uniqueKey = Symbol();
  thisArg[uniqueKey] = this;
  // 使用数组的方式执行函数
  const result = thisArg[uniqueKey](...argsArray);
  // 执行完毕后删除临时属性
  delete thisArg[uniqueKey];
  return result;
};

手写bind()

Function.prototype.myBind = function(thisArg, ...boundArgs) {
  // 返回一个新的函数
  const self = this;

  // 返回的新函数,接受后续传入的参数
  return function(...args) {
    // 使用 apply 调用原始函数,绑定 this 并传递参数
    return self.apply(thisArg, [...boundArgs, ...args]);
  };
};

全部评论
apply()实现里,argsArray可能是undefined
点赞 回复 分享
发布于 03-22 16:09 上海
这个面试会要求手撕代码吗 好难呀
点赞 回复 分享
发布于 02-03 22:22 湖南

相关推荐

03-01 21:45
中北大学 golang
孤蓝长空:请你说一下为什么你用websocket而不是http,请你说一下什么是rpc,为什么用rpc,你的rpc的传输协议是JSON,xml还是什么 请你描述一下你的鉴权流程(完整的) 我问的是第二个项目,随便问的哈哈哈
开工第一帖
点赞 评论 收藏
分享
评论
点赞
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务