(共566篇)
全部分类

js解读-Function.prototype.apply.call()
[ JS基础 ] 

今天又有人问我Function.prototype.apply.call()是啥意思了,干脆在这里总结一下

首先回忆一下 apply 和 call 的用法:

applycall都用于改变函数的执行上下文,并且传递参数(两者传递参数的方式不同, call以序列化参数传参,apply以数组形式传参)

1
2
3
4
5
6
let egg = { name: 'pear' };
function add(color) {
    return this.name + "'s color is " + color;
}
add.call(egg, 'yellow'); // "paer's color is yellow"˝
add.apply(egg, ['yellow']); // "paer's color is yellow"

相当于

1
2
3
4
5
6
7
8
function add(color) {
    return this.name + "'s color is " + color;
}
let egg = {
    name: 'pear',
    add,
};
egg.add('yellow'); // "paer's color is yellow"

现在来把Function.prototype.apply.call(target, context, [...argList])拆分一下:

Function.prototype.apply当做一个函数fn,

那就是fn.call(target, context, [...argList])

相当于target.fn(context, [...argList])

通常情况下,我们的target都是一个对象,用来设置call方法的执行上下文

但是如果我们把target设置成一个函数呢?函数时可以执行apply方法的。

现在再把 fn 展开target.apply(context, [...argList]),你会发现是不是又回到了apply的用法。

其中:

target是一个函数,

contexttarget函数的执行上下文,

[...argList]是通过apply执行函数的传参内容。

到此Function.prototype.apply.call(target, context, [...argList])就解读完毕了

扩展

实际上不是非要使用这种格式Function.prototype.apply.call(target, context, [...argList])

我们也可以使用

Function.prototype.apply.apply(target, [context, [...argList]])

Function.prototype.call.call(target, context, ...argList)

Function.prototype.call.apply(target, [context, ...argList]])

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function add(color) {
    return this.name + "'s color is " + color;
}
let egg = {
    name: 'pear',
};

Function.prototype.apply.apply(add, [egg, ['red']]); // "pear's color is red"
Function.prototype.apply.apply(add, [egg, ['yellow']]); // "pear's color is red"
Function.prototype.call.apply(add, [egg, ['yellow']]); // "pear's color is red"
Function.prototype.call.call(add, egg, 'yellow'); // "pear's color is red"

可以发现这四种写法的结果都是一样的,具体的分解原理和上面是一样的,就不再细说了。