对比学习 apply, call, 和 bind 👀👀👀

前言

大家好 , 我是一名在校大二学生 , 今天学习apply, call, 和 bind , 我决定将三者对比学习 , 分别从 :

  • 相同点
  • 差异点
  • 易错点

横向对比

在 JavaScript 开发中,apply, call, 和 bind 是非常常用的函数方法,它们都用于改变函数的 this 上下文。本文将详细介绍这三者的相同点、区别以及易错点,并通过代码示例来加深理解。

相同点

  1. 改变 this 上下文 :这三个方法都可以改变函数调用时的 this 值。
  2. 立即执行 vs 延迟执行applycall 会立即执行函数,而 bind 会返回一个新函数,可以在之后调用。
代码示例
js 复制代码
function greet(name) {
    console.log(`Hello, ${name}! I am ${this.name}`);
}

const person = { name: 'Alice' };

// 使用 call
greet.call(person, 'Bob'); // Hello, Bob! I am Alice

// 使用 apply
greet.apply(person, ['Charlie']); // Hello, Charlie! I am Alice

// 使用 bind
const greetAlice = greet.bind(person);
greetAlice('Dave'); // Hello, Dave! I am Alice

差异点

  1. 参数传递方式
    • call:参数以逗号分隔的形式传递。
    • apply:参数以数组形式传递。
    • bind:参数以逗号分隔的形式传递,但返回的是一个新函数,可以在之后调用。
代码示例
javascript 复制代码
function sum(a, b, c) {
    return a + b + c;
}

const numbers = [1, 2, 3];

// 使用 call
console.log(sum.call(null, 1, 2, 3)); // 6

// 使用 apply
console.log(sum.apply(null, numbers)); // 6

// 使用 bind
const sum12 = sum.bind(null, 1, 2);
console.log(sum12(3)); // 6
  1. 返回值
    • callapply:返回函数的执行结果。
    • bind:返回一个新函数,可以在之后调用。
代码示例
js 复制代码
function getGreeting(name) {
    return `Hello, ${name}! I am ${this.name}`;
}

const person = { name: 'Alice' };

// 使用 call
const greetingCall = getGreeting.call(person, 'Bob');
console.log(greetingCall); // Hello, Bob! I am Alice

// 使用 apply
const greetingApply = getGreeting.apply(person, ['Charlie']);
console.log(greetingApply); // Hello, Charlie! I am Alice

// 使用 bind
const getGreetingAlice = getGreeting.bind(person);
const greetingBind = getGreetingAlice('Dave');
console.log(greetingBind); // Hello, Dave! I am Alice

易错点

  1. this 上下文的默认值

    • 在严格模式下,this 默认为 undefined
    • 在非严格模式下,this 默认为全局对象(浏览器中是 window,Node.js 中是 global)。
代码示例
scss 复制代码
function logThis() {
    console.log(this);
}

// 严格模式
(function() {
    'use strict';
    logThis.call(); // undefined
})();

// 非严格模式
logThis.call(); // window 或 global
  1. bind 返回的新函数的 this 上下文
  • bind 返回的新函数的 this 上下文是固定的,即使使用 callapply 也无法改变。
代码示例
javascript 复制代码
function logThis() {
    console.log(this);
}

const boundLogThis = logThis.bind({ name: 'Alice' });

boundLogThis.call({ name: 'Bob' }); // { name: 'Alice' }
  1. apply call 的性能
  • apply 需要将参数数组展开,性能略低于 call
代码示例
js 复制代码
function sum(a, b, c) {
    return a + b + c;
}

const numbers = [1, 2, 3];

console.time('call');
for (let i = 0; i < 1000000; i++) {
    sum.call(null, 1, 2, 3);
}
console.timeEnd('call'); // call: 10ms

console.time('apply');
for (let i = 0; i < 1000000; i++) {
    sum.apply(null, numbers);
}
console.timeEnd('apply'); // apply: 15ms

总结

apply, call, 和 bind 都是改变函数 this 上下文的强大工具,但它们在参数传递方式、立即执行 vs 延迟执行、返回值等方面有所不同。理解这些差异和易错点,可以帮助我们在实际开发中更灵活地使用这些方法,提高代码的可读性和可维护性。

希望本文对你有所帮助!如果有任何疑问或建议,欢迎在评论区留言交流。

相关推荐
jt君424267 小时前
React Native JSI 深入剖析 — 第 5 部分中文技术整理:用 HostObject 把 C++ 类暴露给 JavaScript
前端·react native
胡萝卜术7 小时前
滑动窗口最大值:从暴力到单调队列,层层优化全解析
前端·javascript·面试
fluffyox7 小时前
Notion 的公式栏里,藏着一台虚拟机——逆向 + 用 600 行 JS 复刻它的编译器与栈式 VM
前端
kyriewen8 小时前
2026 年了,这 6 个 npm 包可以卸载了——浏览器原生 API 已经能替代
前端·javascript·npm
沉默王二9 小时前
面试结束后,我反问:“就面个实习至于上这么大强度吗?”面试官:“你对 RAG、Agent、MCP、Skill 理解得很到位,所以要求高一点。”
面试·agent·ai编程
铁皮饭盒10 小时前
bun直接tsx,优雅!
javascript·后端
Csvn11 小时前
Monorepo 迁移血泪史:从 Multi-Repo 到 Turborepo,这 3 个坑我帮你踩完了
前端
星栈11 小时前
Dioxus 多页面怎么做:`dioxus-router`、嵌套路由、`Outlet` 和页面组织,一篇给你讲顺
前端·rust·前端框架
用户9874092388711 小时前
用 Remotion + edge-tts 打造中文教学视频全自动流水线
前端
风骏时光牛马11 小时前
Less前端工程化实战:变量混合器与项目样式分层落地
前端