前端 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]);
  };
};

全部评论

相关推荐

no_pessimi...:感觉字节都是hr捞人面试的
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
📍面试公司:泽鹿视界🕐面试时间:2025.10.11💻面试岗位:前端开发工程师(实习)❓面试问题:1.自我介绍2.fetch的流式渲染是怎么实现的3.虚拟滚动优化长列表是如何实现的,为什么能优化帧率,什么指标4.骨架屏有什么作用,前端性能优化参考什么指标5.CDN、增量渲染,为什么能减缓抖动6.宏任务、微任务、事件循环7.HTTPS的TLS协议8.手写防抖9.一道特复杂的this指向问题10.call()、apply()、bind()的区别🙌面试感想:只有一面,技术面和hr面一起面,长达1h说一下我的面试感受,前期拷打我的项目,后面问我技术内容,涉及的八股非常少,还有js手写、场景题。主播当天头脑昏昏沉沉的,答的不是很好,然后面试的教室中间突然有人进来开组会,主播只能蹲到走廊上面试了,估计是要挂了。猪脑子又忘记录音了,今天实在打不起精神,导致我连问了什么都不知道了,在走廊上蹲的手脚都麻木了,然后后面hr问些奇奇怪怪的东西:你的同门是如何评价你的、你从小学到现在的成长历程、boss是怎么投递的、他们公司的口号是什么进取,自省,问我怎么理解的…后面还有一大推介绍公司的,其实到这里我已经脑子一片空白了,也没有心思听她讲了什么了,只想早点结束面试,好在这是小厂,本来也没打算去。总结一下,面试的时候一定要有一个好的环境,好的状态,不然面下来特别吃力,全程不知道在干嘛。
发面经攒人品
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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