js apply和call

先看定义

call方法

  • 语法:fun.call(thisArg, arg1, arg2, …)
  • 定义:call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。

    参数

    • thisArg
      • 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
    • arg1, arg2, …
      • 指定的参数列表。

apply方法

  • 可以看MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
  • 语法:fun.apply(thisArg, [argsArray])
  • 定义:apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。

    参数

    • thisArg
      • 在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
    • argsArray
      • 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。

注意

call()方法的作用和apply()方法类似,只有一个区别,就是call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组

参考http://www.360doc.com/content/13/0807/19/13328522_305431575.shtml

MDN的解释有点官方,新手看容易懵,所以从网上找了其它的解释。

call和apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性。(只是参数列表不一样)

apply示例

1
2
3
4
5
6
7
8
9
10
function Person (name, age) {
this.name = name;
this.age = age; // 这里的 this 指的是 Person 函数
}
function Student (name, age, grade) {
Person.apply(this, arguments);
this.grade = grade; // 这里的 this 指的是 Student 函数
}
var student = new Student('qian', 21, '一年级');
console.log("name:"+student.name+'\n'+"age:"+student.age+'\n'+"grade:"+student.grade);

分析:Person.apply(this, arguments);

  • this:在下面创建对象的时候代表student对象
  • arguments:是一个数组,也就是[‘qian’, ‘21’, ‘一年级’]
  • 也就是通俗一点讲就是:用 student 去执行 Person 这个类里面的内容,在 Person 这个类里面存在 this.name 等之类的语句,这样就将属性创建到了 student 对象里面

call示例,只需要在 Student 函数里面将 apply 修改如下:Person.call(this, name, age);

apply的一些其他巧妙用法

定义 Person 函数时,它的参数并不是数组,可是 apply 方法传递的却是数组,并且 Person 函数能够正确解析,这是为什么呢?

这个就是 apply 的一个巧妙用处,可以将一个数组默认的转换为一个参数列表,如 [param1, param2, param3] 转换为 (param1, param2, param3)。

和 Math.max 联合使用得到数组中最大的元素。因为 Math.max 参数里面不支持数组,所以可以这样来使用 var max = Math.max.apply(null, array).

同样,Math.min 也可以。

Array.prototype.push 与 apply 联合使用。

由于 push 方法没有提供 push 一个数组,但是它提供了 push(param1, param2,…paramN),所以同样可以通过 apply 来转换一下。

1
2
3
4
var arr1 = new Array("1", "2", "3");
var arr2 = new Array("4", "5", "6");
Array.prototype.push.apply(arr1,arr2);
arr1 // ["1", "2", "3", "4", "5", "6"]

总结:该文章主要摘抄自网上大神,末尾的一些应用方法真的很巧妙,不是初学者能想到的,但是一定要知道,学无止境!

后续更新,自己在网上看到前辈讲解后跟着实现了一遍:https://github.com/lizhongzhen11/myStudy/blob/master/js/call_apply.js

Newer Post

js map、forEach、filter、reduce、some、every

请参考 MDN1.map方法 概述:map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 语法:123let array = arr.map(function callback(currentValue, index, array) { // …

继续阅读
Older Post

Vue router小知识点

之前学习大神后台系统时发现一个问题没搞懂,仔细看了 vue-router 文档才明白 先举个小例子:123456789101112131415161718192021222324252627282930313233343536373839<script src="https://u …

继续阅读