浅谈JS中call()和apply()的区别和用途?

简介: 前言:在JavaScript中,this指向问题一直是一个老生常谈的问题。很多小伙伴应该都知道在js中,this指向哪里通常是在函数调用的时候才确定的,简单来说就是谁调用了函数则this指向谁,当然,这只是狭义的,更加详细的介绍大家可以去看《你不知道的Javascript》这本书。call()和apply()这两个方法的作用可以简单归纳为改变this指向,从而让我们的this指向不在是谁调用了函数就指向谁。

1.call()和apply()简介


在JavaScript中,每个函数对象都带有call()和apply()方法,即Function.prototype.call()和Function.prototype.apply(),这两个方法都是挂载在原型上的。


MDN官方解释如下:


call:

**call()** 方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。


apply:

**apply()**方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。


通过官网的解释,大家可能对这两个方法有了一个大致的了解,其实简单来说,call和apply两个方法最主要的作用就是改变this指向。


2. call()和apply()使用方法


call:

function.call(thisArg, arg1, arg2, ...)


apply:

func.apply(thisArg, [argsArray])


参数说明:


thisArg: 函数在运行时的this值,如果函数处于非严格模式下,则指定为 nullundefined 时会自动替换为指向全局对象。


arg1, arg2, ...和_[argsArray_]:函数接收的参数列表。


3.this指向简单示例


代码示例:

<script>
  let obj1 = {
    name: "张三",
    age: 24,
    user: function (args) {
      console.log("姓名:", this.name);
      console.log("年龄:", this.age);
      console.log("参数", args);
    }
  }
  let obj2 = {
    name: "李四",
    age: 30,
    user: function () {
      console.log("姓名:", this.name);
      console.log("年龄:", this.age);
      console.log("参数", args);
    }
  }
  // 正常的调用
  obj1.user('我是参数');
  obj2.user('我是参数');
</script>

输出结果

1.png


输出结果


上段代码中声明了两个对象obj1和obj2,对象中包括了一些常规属性和一个方法属性。然后在最后分别调用了对象中的两个方法,方法中的this指向不出意外的指向了我们的调用者,方法中的name和age就是当前对象中声明的值


4.使用call()和apply()方法改变this指向


代码示例:

<script>
  let obj1 = {
    name: "张三",
    age: 24,
    user: function (args) {
      console.log("姓名:", this.name);
      console.log("年龄:", this.age);
      console.log("参数", args);
    }
  }
  let obj2 = {
    name: "李四",
    age: 30,
    user: function (args) {
      console.log("姓名:", this.name);
      console.log("年龄:", this.age);
      console.log("参数", args);
    }
  }
  // 正常的调用
  // obj1.user('我是参数');
  // obj2.user('我是参数');
  // 改变this指向
  obj1.user.call(obj2, "我是参数"); // 使用call方法改变
  obj2.user.apply(obj1, ["我是参数"]); // 使用apply方法改变
</script>


输出结果:

2.png



输出结果


由上面输出结果可以看出,结果恰好和正常的this指向的结果相反,因为我们使用call方法和apply方法改变了this指向,即当我们调用obj1.user方法时,将this的指向变为了obj2,所以方法中答应出了obj2中的属性值。


5.call与apply的区别


MDN上有这样一段让读者注意的话:

注意:call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组


由上面可以得出:两个方法没有什么区别,唯一的区别就是接收的参数不同,一个接收参数列表,一个接收参数数组,才上面的代码示例中也可以看出来。


总结:


call()和apply()两个方法很相似,但是又有些许的不同,在开发中可能很多小伙伴没有用过,但是其实它们的使用场景是很多的,比如:Math.max.apply(null, array)等。

相关文章
|
18天前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
24 1
|
1月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
2月前
|
JavaScript 前端开发
JS高级—call(),apply(),bind()
【10月更文挑战第17天】call()`、`apply()`和`bind()`是 JavaScript 中非常重要的工具,它们为我们提供了灵活控制函数执行和`this`指向的能力。通过合理运用这些方法,可以实现更复杂的编程逻辑和功能,提升代码的质量和可维护性。你在实际开发中可以根据具体需求,选择合适的方法来满足业务需求,并不断探索它们的更多应用场景。
13 1
|
2月前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
92 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
2月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
21 2
|
2月前
|
JavaScript 前端开发
js 中call()和apply()
js 中call()和apply()
29 1
|
2月前
|
JavaScript 前端开发
【JavaScript】let,const和var的区别
总的来说,随着ECMAScript 6(ES6)及后续版本的推广,`let`和 `const`因其增强的块级作用域和对变量行为的更严格控制,逐渐成为现代JavaScript编码实践中推荐使用的变量声明方式。而 `var`由于其历史遗留的局限性,正逐渐被边缘化,但在维护老代码或处理特定兼容性需求时仍需了解。
38 3
|
3月前
|
JavaScript 前端开发
JavaScript中单引号和双引号的效果的一点区别
JavaScript中单引号和双引号的效果的一点区别
|
3月前
|
自然语言处理 JavaScript 前端开发
JS中this的应用场景,再了解下apply、call和bind!
该文章深入探讨了JavaScript中`this`关键字的多种应用场景,并详细解释了`apply`、`call`和`bind`这三个函数方法的使用技巧和差异。
|
4月前
|
JavaScript 前端开发
深入浅出 妙用Javascript中apply、call、bind
【8月更文挑战第1天】深入浅出 妙用Javascript中apply、call、bind
31 0