为什么要使用“申请”?

IT技术 javascript
2021-03-08 04:34:54

这段代码摘自 JavaScript Ninja 的秘密。

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

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

5个回答

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

使用.apply(),传递多少参数并不重要。您可以将集合提供给console.log(),它们将作为单独的参数到达。

所以如果你这样做:

console.log(arguments)

...你实际上是在给console.log一个Arguments对象。

但是当你这样做时:

console.log.apply( console, arguments );

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

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

一个典型的调用是这样的:

var max = Math.max( 12,45,78 );  // returns 78

...它返回最大的数字。

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

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

如您所见,我们不需要提前知道将传递多少个参数。Array 可以有 5 或 50 个项目。无论哪种方式它都会起作用。

实际上,在 Firebug 中,您也可以使用 console.log(arguments),这将导致几乎相同的结果。但我不确定其他浏览器。
2021-04-27 04:34:54
@ user113716 - 为什么第一个参数是Math.max.apply null
2021-04-29 04:34:54
@kirilloid:是的,有点。Firebug 和 Chrome 将显示 Arguments 对象的内容,但仍将其视为一个参数。您将失去多个参数的好处,就像您这样做一样:log('value was %s',str);wherestr是包含要合并到字符串中的值的变量。而不是"value was theValue",你会得到['value was %s','theValue']
2021-05-06 04:34:54
除了一件事,我得到了一切,当你调用 console.log.apply(x,y) 时,它是否真的调用了 console.log 函数 n 次,其中 n 是数组中的索引数量?或者它只被调用一次并连接了值或其他什么?
2021-05-12 04:34:54

如果你有

function log() {
    console.log.apply(console, arguments);
}

并称其为log('foo');then 转换为console.log.apply(console, ['foo']);哪个相当于console.log('foo');您想要的。

如果你定义它像

function log() {
    console.log(arguments);
}

相反,那么log('foo');将相当于log(['foo']);哪个不是你想要的。

因此,简而言之,apply允许您将单个参数数组传递给函数,就好像它们是不同的参数一样。
2021-05-05 04:34:54

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.

或者,另一种用途:改变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.
+1 表示:“apply 函数改变了被调用者中 this 的值”
2021-04-29 04:34:54
在这种情况下,this无论哪种方式都是相同的。
2021-05-07 04:34:54
您的评论具有误导性,使用 apply 的实际原因是另一个。* 我没有拒绝你的回答——只是解释了 ;-)
2021-05-17 04:34:54

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

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

变量函数:

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

数据结构是 JavaScript:

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

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

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

average(1,2,3);
average(1);
average(3,5,6,7,8);

如果以数组格式获取数据(在大多数情况下,我们将以数组格式获取可变参数函数的数据),那么我们需要调用我们的函数,例如 -

average(array[0],array[1],array[2],array[3],.... and so on)

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

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

average.apply(null,array);
为什么不在函数中接受数组形式的参数,而是像 abc([1,2,3]) 一样调用函数 abc ,并相应地处理函数中的数组?为什么这么复杂?
2021-05-17 04:34:54

console.log(arguments)将向 发送一个参数console.log,即传递给日志方法的参数数组。console.log.apply(console, arguments)将可能的多个参数作为多个参数而不是单个数组发送。