js 中 call、apply、bind 方法的原理与应用

方法 call apply bind
参 多个 单个数组 多个
作用 函数调用改变this 同理 同理
果 直接执行的 直接执行的 返回待执行函数

基本概念

call、apply 和 bind 是 Function 对象的三个方法,用于改变函数执行时的 this 指向:

javascript 复制代码
func.call(thisArg, param1, param2, ...)
func.apply(thisArg, [param1, param2, ...])
func.bind(thisArg, param1, param2, ...)
  • 在浏览器里,在全局范围内this指向window对象;
  • 在函数中,this永远指向最后调用他的那个对象;
  • 构造函数中,this指向new出来的那个新的对象;

  • call、apply、bind中的this被强绑定在指定的那个对象上;
  • 箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;
  • apply、call、bind都是js给函数内置的一些API,调用他们可以为函数指定this的执行,同时也可以传参。

this 指向规则

  1. 全局范围内:this 指向 window 对象
  2. 函数中:this 指向最后调用它的对象
  3. 构造函数中:this 指向 new 出来的新对象
  4. call/apply/bind:this 被强绑定在指定对象上
  5. 箭头函数:this 为父作用域的 this(静态绑定)

方法区别

方法 参数形式 执行时机 返回值
call 参数列表 立即执行 函数返回值
apply 参数数组 立即执行 函数返回值
bind 参数列表 不立即执行 返回绑定函数

应用场景

1. 判断数据类型

javascript 复制代码
function getType(obj) {
  let type = typeof obj;
  if (type !== "object") return type;
  return Object.prototype.toString.call(obj).replace(/^$/, '$1');
}

2. 类数组借用数组方法

javascript 复制代码
var arrayLike = {
  0: 'java',
  1: 'script',
  length: 2
}

Array.prototype.push.call(arrayLike, 'jack', 'lily');
// {0: "java", 1: "script", 2: "jack", 3: "lily", length: 4}

3. 获取数组最大/最小值

javascript 复制代码
let arr = [13, 6, 10, 11, 16];
const max = Math.max.apply(Math, arr);
const min = Math.min.apply(Math, arr);

手动实现

实现 bind

javascript 复制代码
Function.prototype.myBind = function(context) {
  if (typeof this !== 'function') throw new TypeError('Error');
  
  const _this = this;
  const args = [...arguments].slice(1);
  
  return function F() {
    if (this instanceof F) {
      return new _this(...args, ...arguments);
    }
    return _this.apply(context, args.concat(...arguments));
  }
}

实现 call

javascript 复制代码
Function.prototype.myCall = function(context) {
  context = context || window;
  context.fn = this;
  
  const args = [...arguments].slice(1);
  const result = context.fn(...args);
  
  delete context.fn;
  return result;
}

实现 apply

javascript 复制代码
Function.prototype.myApply = function(context = window, ...args) {
  const key = Symbol('key');
  context[key] = this;
  
  const result = context[key](args);
  delete context[key];
  
  return result;
}

总结

这三个方法的核心原理都是通过改变函数的 this 指向来实现"借用"方法的功能。在实际开发中,它们常用于:

  • 改变函数上下文
  • 实现函数借用
  • 实现柯里化(bind)
  • 处理类数组对象
  • 实现更灵活的函数调用方式
相关推荐
开开心心就好9 分钟前
竖式除法出题工具,整除余数混合模式
运维·服务器·前端·javascript·ocr·perl·1024程序员节
起个名字费劲死了18 分钟前
Halcon学习一:骰子识别
前端·python·学习
大江东去浪淘尽千古风流人物23 分钟前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
其实防守也摸鱼27 分钟前
Chrome 扩展安全攻防实录:从攻击面到防御实践
开发语言·前端·网络·chrome·安全·web安全·php
web打印社区31 分钟前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
李剑一44 分钟前
为什么几乎所有的知名开源项目都是外国人写的?
前端·ai编程·deepseek
小郎君6581 小时前
(一)为什么表单需要第三种状态:disabled、readonly 与纯文本展示
前端·vue.js
计算机魔术师1 小时前
1.4万亿没人接,OpenAI自己砍了1500亿
前端
溪语流沙2 小时前
【每天一个CSS | Day41】开关三连:一套状态机,三种视觉翻译
前端·css·html5·每日一练·按钮
变与不变8062 小时前
css定位布局精讲
前端·css