【问题标题】:How to use apply method with string array?如何在字符串数组中使用 apply 方法?
【发布时间】:2017-09-09 09:14:06
【问题描述】:

谁能给我解释一下为什么我不能在字符串数组上正确使用 apply 方法?

function speak(line) {
     console.log(line);
}
var whiteRabbit = {type: "white", speak: speak};
speak.apply(whiteRabbit, ["Burp!","Skree","Hello"]);

输出是Burp,为什么不是整个数组?以及如何使用 apply 方法来实现?

【问题讨论】:

  • 什么是胖兔?
  • 抱歉应该是whiteRabbit....我该如何纠正这个问题

标签: javascript arrays apply


【解决方案1】:

来自Function#apply

apply() 方法调用具有给定this 值的函数,并且arguments 作为数组(或array-like object)提供。

您只将数组的第一个元素作为参数line。如果您采用更多参数,您也可以看到数组的其余部分。

function speak(line, line1, line2) {
    console.log(line);
    console.log(line1);
    console.log(line2);
}

var whiteRabbit = {
    type: "white",
    speak: speak
};

speak.apply(whiteRabbit, ["Burp!", "Skree", "Hello"]);

如果您喜欢将值用作数组,您可以使用 arguments 并迭代这些值。

function speak() {
    Array.prototype.forEach.call(arguments, function (s) {
        console.log(s);
    });
}

var whiteRabbit = {
    type: "white",
    speak: speak
};

speak.apply(whiteRabbit, ["Burp!", "Skree", "Hello"]);

你可以使用 ES6 rest parameters ...

function speak(...args) {
    args.forEach(s => console.log(s));
}

var whiteRabbit = {
    type: "white",
    speak: speak
};

speak.apply(whiteRabbit, ["Burp!", "Skree", "Hello"]);

【讨论】:

  • 感谢您的回答!所以让它动态,我应该使用arguments.length。对吗?
  • @rajeev 甚至更好的休息/扩展语法:function speak(...args){ console.log(...args);}
【解决方案2】:

Function#apply 将数组扩展为函数参数,因为您的唯一参数是 line,因此将数组中的第一项分配给它,其余的将被忽略。

btw - 由于speak 函数不以任何方式使用this,因此apply 的第一个参数在这种情况下无关紧要。

如果您向函数添加更多参数,您可以看到它是如何工作的:

function speak(a, b, c) {
     console.log(a, b, c);
}

speak.apply(null, ["Burp!","Skree","Hello"]);

如果您需要显示一个未知长度的数组,最好使用Function#call 调用该函数,然后对数组进行迭代,或者将其转换为可以呈现的东西。例如:

function speak(arr) {
  console.log(arr.join(' '));
}

speak.call(null, ["Burp!", "Skree", "Hello", "Cats"]);

【讨论】:

    【解决方案3】:

    你需要添加更多参数

    function speak(line, line2, line3) {
         console.log(line, line2, line3);
    }
    var whiteRabbit = {type: "white", speak: speak};
    speak.apply(whiteRabbit, ["Burp!","Skree","Hello"]);

    【讨论】:

      【解决方案4】:

      你可以让兔子一个接一个地说:

       ["Burp!","Skree","Hello"].forEach( speak );
      

      如果你也想改变上下文:

      ["Burp!","Skree","Hello"].forEach( word => speak.call(rabbit, word));
      

      【讨论】:

        【解决方案5】:

        我将假设 fatRabbit 应该是 whiteRabbit,而您的问题是为什么您只看到 Burp! 而不是整个数组。

        原因是apply 使用数组调用带有离散参数 的函数,因此第一个条目显示为line 参数,而您看不到其他条目,因为你没有他们的参数。

        如果要查看数组,请使用call 而不是apply;那么line 将引用数组,而不仅仅是第一个条目:

        function speak(line) {
             console.log(line);
        }
        var whiteRabbit = {type: "white", speak: speak};
        speak.call(whiteRabbit, ["Burp!","Skree","Hello"]);

        或者,在方法中添加更多参数 (speak(line1, line2, line3))。


        在评论中,你问过:

        你能说明如何使它动态吗?

        如果“动态”是指它记录尽可能多的条目,我会使用call(如上)和一个循环:

        function speak(lines) {
            lines.forEach(function(line) {
                console.log(line);
            });
        }
        var whiteRabbit = {type: "white", speak: speak};
        speak.call(whiteRabbit, ["Burp!","Skree","Hello"]);

        这是使用forEach,但you have lots of other options

        【讨论】:

        • 感谢您的回答!你能展示一下如何让它充满活力吗?
        • @RajeevHanda:“动态”是什么意思?
        • @RajeevHanda:我猜了你上面动态的意思。
        猜你喜欢
        • 1970-01-01
        • 2010-12-18
        • 1970-01-01
        • 1970-01-01
        • 2020-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多