js函数执行call()和apply()

call()和apply()的共同点

1-都是函数对象的方法,需要通过函数对象调用。

2-当函数调用call()和apply()都会执行

3-在调用call()和apply()时,可以将一个对象指定为第一个参数传进去,此时这个对象会变成函数执行时的this

call()和apply()的区别

call()可以将参数实参在对象之后依次传递,列如下

fun.call(obj,2,3,3)

apply()需要将实参封装到一个数组中统一传递,列如下

fun.apply(obj,[2,3,3])

 

在 JavaScript 中,`call` `apply` 是函数对象的两个内置方法,它们用于 **显式地指定函数执行时的 `this` 值**,并调用该函数。它们的主要作用是改变函数的上下文(context),常用于借用方法、函数复用实现继承等场景。 --- ### ✅ 共同点 - 都能立即执行函数 - 都可以指定函数运行时的 `this` 值 - 都可用于函数借用参数传递 --- ## 🔧 1. `function.call(thisArg, arg1, arg2, ...)` 语法: ```js func.call(thisArg, arg1, arg2, ...); ``` - `thisArg`:设置 `func` 内部 `this` 的值 - 参数以 **逐个列出** 的形式传入 ### 示例: ```javascript function greet(greeting, punctuation) { console.log(`${greeting}, I'm ${this.name}${punctuation}`); } const person = { name: 'Alice' }; greet.call(person, 'Hello', '!'); // 输出: Hello, I'm Alice! ``` --- ## 🔧 2. `function.apply(thisArg, [argsArray])` 语法: ```js func.apply(thisArg, [arg1, arg2, ...]); ``` - `thisArg`:同上 - 第二个参数是一个 **数组或类数组对象**,表示要传给函数的参数列表 ### 示例: ```javascript function greet(greeting, punctuation) { console.log(`${greeting}, I'm ${this.name}${punctuation}`); } const person = { name: 'Bob' }; greet.apply(person, ['Hi', '?']); // 输出: Hi, I'm Bob? ``` --- ## ✅ 核心区别总结 | 特性 | `call` | `apply` | |------|--------|---------| | 参数传递方式 | 逐个传参:`call(this, a, b, c)` | 数组传参:`apply(this, [a, b, c])` | | 使用场景 | 参数数量固定已知 | 参数是数组或动态获取 | --- ## 🔄 如何互相模拟? ### 使用 `apply` 模拟 `call` ```js Function.prototype.myCall = function (thisArg, ...args) { return this.apply(thisArg, args); }; ``` ### 使用 `call` 模拟 `apply`(需要借助 `arguments` 或展开) ```js Function.prototype.myApply = function (thisArg, args) { return this.call(thisArg, ...args); }; ``` > 注意:现代 JS 中可以用扩展运算符轻松转换 --- ## 💡 实际应用案例 ### 1. 借用数组方法(处理类数组) ```js function logArgs() { const args = Array.prototype.slice.apply(arguments); // 将 arguments 转为数组 console.log(args); } logArgs(1, 2, 3); // [1, 2, 3] ``` ### 2. 继承:构造函数继承 ```js function Parent(name) { this.name = name; } function Child(name, age) { Parent.call(this, name); // 借用父构造函数 this.age = age; } const child = new Child('Tom', 10); console.log(child); // { name: 'Tom', age: 10 } ``` ### 3. Math.max 处理数组 ```js const numbers = [5, 2, 8, 1]; console.log(Math.max.apply(null, numbers)); // 8 // 等价于 Math.max(...numbers) —— 现代写法 ``` --- ## ⚠️ 注意事项 - 如果 `thisArg` 是 `null` 或 `undefined`,非严格模式下 `this` 指向全局对象(浏览器中是 `window`),严格模式下就是传入的值。 - 在 ES6+ 中,推荐使用 **扩展运算符** 替代 `apply` 来传数组: ```js Math.max(...[1, 2, 3]); // 更简洁 func.call(obj, ...args); // 替代 apply ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值