1.4.6 call, apply
用提供的对象来调用特定函数
call() 和 apply() 使用给定的 this 值和参数来调用指定的函数。
Function.prototype.call()Function.prototype.apply()
它两的功能几乎相同,只是参数不同。
// call() 接受参数列表
fn.call(this, 'apples', 'bananas');
// apply() 接受单个参数数组/类数组对象
fn.apply(this, ['apples', 'bananas']);
fn.apply(this, arguments);
fn.apply(this, {'length':2, '0':'eat', '1':'bananas'});再配合函数的 arguments 参数和剩余参数 (...args) => {},以及展开语法 ...,这两个函数可以说是一模一样。文中的所有例子,call() 和 apply() 都可以相互替代。
1. 语法
// call
call();
call(thisArg);
call(thisArg, arg1, /* …, */ argN);
// apply
apply(thisArg);
apply(thisArg, argsArray);参数
thisArg:在调用函数时使用的this值参数列表
arg1, ..., argN(可选),an argument list参数数组或类数组
argsArray(可选),a single array of arguments类数组对象:有
length属性,支持整数下标索引[]
返回值:使用指定的
this值和参数调用函数的结果
对于一个现有的函数,我们可以给它分配一个不同的 this 对象来进行调用。
有了 call() 和 apply(),一个对象的函数或方法就能被另外一个不同的对象来调用了,这样就能让我们只编写一次方法,然后在另一个对象中直接使用。
2. 常见用法
2.1 对象的构造函数
使用 call 可以链接到对象的构造函数(类似于 Java)。
以上代码,完成了 Food 和 Toy 对 Product 的继承。
2.2 调用函数
eg1. 调用函数,并指定上下文
eg2. 调用函数,且没有传第一个参数
eg3. 调用匿名函数
2.3 合并数组
我们可以使用 Array.prototype.push() 把一个或多个元素添加到数组的末尾。但如果给它传一个数组, push() 将会把这个数组作为一个整体(即单个元素),而不是依次添加数组里的元素。
而已有的 Array.prototype.concat() 是创建并返回一个新数组,而不是在现有的数组上追加。
在这种情况下,我们就可以使用 apply() 将数组隐式地“展开”成一系列的参数列表。
2.4 内置函数
巧妙地使用 apply() 可以让我们更灵活地使用内置函数。
需要注意的是,通过这种方式使用 apply() 和 call(),可能会超出 JavaScript 引擎的参数长度限制,比如 JavaScriptCore 引擎的硬编码参数限制是 65536。所以若会超长,可以考虑先将数组分块。
3. 主要参考
Last updated