js函数之call和apply

一、含义

function test() {
    console.log('----')
}

//执行
test();
test.call()

        结果一致,调用test()默认会调用call,二者效果一致,call省略掉了。

二、改变this指向

        call还有一个很重要的功能是改变this的指向。

function Car(brand, color) {
    this.brand = brand;
    this.color = color;
    this.run = function () {
        console.log('run 方法')
    }
}

let newCar = {
    age: 30
}

1、不用 call

console.log('newCar', newCar)

打印结果:{}

2、使用 call

//参数1:对象,参数2,3,4……:其他参数
Car.call(newCar, '兰博基尼', 'red')
console.log('newCar', newCar)

打印结果:

{
   "brand": "兰博基尼",
   "color": "red"
}

        可以看出改变了this 的指向,和apply的区别是后面是一个数组,其他没啥区别,均可以改变this 指向Car.apply(newCar, ['兰博基尼', 'red'])。

三、应用

function Compute() {
    this.plus = function (a, b) {
        console.log(a + b)
    }
    this.minus = function (a, b) {
        console.log(a - b)
    }
}

function FullCompute() {
    Compute.apply(this)
    this.mul = function (a, b) {
        console.log(a * b)
    }
    this.div = function (a, b) {
        console.log(a / b)
    }
}

const compute = new FullCompute();
compute.plus(1,1);
compute.minus(1,1);
compute.mul(1,1);
compute.div(1,1);

打印结果:

四、全局this和函数this

        全局定义的this和函数内部定义的 this 相当于 window,例如:

function test() {
    this.a = 1;
    let b = 2
}

test();
console.log(a); // 1
console.log(b); // b is not defined

在 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 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值