为什么要用"申请"?

isl*_*205 28 javascript

这个片段是从JavaScript Ninja的Secrets中剪下来的.

function log() {
    try {
        console.log.apply( console, arguments );
    } catch(e) {
        try {
            opera.postError.apply( opera, arguments );
        } catch(e){
            alert( Array.prototype.join.call( arguments, " " ) );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我为什么要使用apply console.log.apply(console, arguments)console.log(arguments)?之间的区别是什么?

use*_*716 36

在这种情况下,日志函数可以接受任意数量的参数.

使用.apply(),传递多少参数无关紧要.您可以将该集合赋予console.log(),并且它们将作为单独的参数到达.

所以,如果你这样做:

console.log(arguments)
Run Code Online (Sandbox Code Playgroud)

......你实际上是在给console.log一个Arguments物体.

但是当你这样做时:

console.log.apply( console, arguments );
Run Code Online (Sandbox Code Playgroud)

......好像你分别通过了它们.

使用.apply()这样的其他有用示例可以在可以接受可变数量的参数的其他方法中得到证明.一个这样的例子是Math.max().

一个典型的电话是这样的:

var max = Math.max( 12,45,78 );  // returns 78
Run Code Online (Sandbox Code Playgroud)

...返回最大数字的地方.

如果您实际拥有需要最大值的数组,该怎么办?您可以使用.apply()传递集合.Math.max会认为它们是作为单独的参数而不是数组发送的.

var max = Math.max.apply( null, [12,45,92,78,4] );  // returns 92
Run Code Online (Sandbox Code Playgroud)

如您所见,我们不需要事先知道将传递多少个参数.数组可以有5或50个项目.无论哪种方式都可以.


Mat*_*rog 13

如果你有

function log() {
    console.log.apply(console, arguments);
}
Run Code Online (Sandbox Code Playgroud)

然后把它称之为log('foo');转换console.log.apply(console, ['foo']);为相当于console.log('foo');你想要的东西.

如果你定义它

function log() {
    console.log(arguments);
}
Run Code Online (Sandbox Code Playgroud)

相反,那log('foo');将等同于log(['foo']);你不想要的.


ick*_*fay 6

apply函数更改了this被调用者的值,并允许您为参数传递数组.

例如,如果要将数组作为参数传递给函数:

function foo(value1, value2, value3) {
    alert("Value 1 is "+value1+".");
    alert("Value 2 is "+value2+".");
    alert("Value 3 is "+value3+".");
}
var anArray=[1, 2, 3];
foo(anArray); // This will not work. value1 will be anArray, and value 2 and 3 will be undefined.
foo.apply(this, anArray); // This works, as anArray will be the arguments to foo.
Run Code Online (Sandbox Code Playgroud)

或者,另一种用途:改变this:

function Foo() {
    this.name="world";
    this.sayHello=function() {
        alert("Hello, "+this.name);
    };
}
var foo=new Foo();
foo.sayHello(); // This works, as this will be foo in foo's sayHello.
var sayHello=foo.sayHello;
sayHello(); // This does not work, as this will not be foo.
sayHello.apply(foo, []); // This will work, as this will be foo.
Run Code Online (Sandbox Code Playgroud)


Ans*_*hul 6

让我们讨论一些背景,为什么apply我们有call类似语法的方法时特别存在.

首先,我们需要了解一些主题:

变异函数:

在计算机编程中,它是一个可以接受任意数量参数的函数.

数据结构是JavaScript:

在javascript中如果我们处理的数据比最常用的数据结构是数组,并且在大多数情况下我们以数组的形式获取数据.

现在,如果我们在javascript中执行任何可变参数函数,那么我们的调用将如下所示 -

average 是一个可变函数,它的调用看起来像,

average(1,2,3);
average(1);
average(3,5,6,7,8);
Run Code Online (Sandbox Code Playgroud)

如果以数组格式获取数据(在大多数情况下,我们将以数组格式获取Variadic函数的数据),而不是像我们需要调用我们的函数一样 -

average(array[0],array[1],array[2],array[3],.... and so on)
Run Code Online (Sandbox Code Playgroud)

如果我们得到一个长度为100项的数组怎么办,我们这样写吗?

不,我们有apply方法,专为此目的而设计.

average.apply(null,array);
Run Code Online (Sandbox Code Playgroud)

  • 为什么不接受函数中数组形式的参数,而只是像 abc([1,2,3]) 一样调用函数 abc ,并相应地处理函数中的数组?为什么这么复杂? (2认同)