JavaScript-variabele aantal argumenten om te functioneren

Is er een manier om “onbeperkte” vars toe te staan ​​voor een functie in JavaScript?

Voorbeeld:

load(var1, var2, var3, var4, var5, etc...)
load(var1)

Antwoord 1, autoriteit 100%

Natuurlijk, gebruik gewoon het object arguments.

function foo() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

Antwoord 2, autoriteit 31%

In (meest) recente browsers kunt u een variabel aantal argumenten accepteren met deze syntaxis:

function my_log(...args) {
     // args is an Array
     console.log(args);
     // You can pass this array as parameters to another function
     console.log(...args);
}

Hier is een klein voorbeeld:

function foo(x, ...args) {
  console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
​    0: "a"
    ​1: "b"
    ​2: "c"
    ​3: "d"
    ​length: 4

Documentatie en meer voorbeelden hier: https:// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters


Antwoord 3, autoriteit 13%

Een andere optie is om uw argumenten in een contextobject door te geven.

function load(context)
{
    // do whatever with context.name, context.address, etc
}

en gebruik het zo

load({name:'Ken',address:'secret',unused:true})

Dit heeft het voordeel dat je zoveel benoemde argumenten kunt toevoegen als je wilt, en de functie kan ze gebruiken (of niet) zoals het goeddunkt.


Antwoord 4, autoriteit 6%

Ik ben het eens met Kens antwoord als het meest dynamische antwoord en ik ga graag een stap verder. Als het een functie is die je meerdere keren aanroept met verschillende argumenten – ik gebruik het ontwerp van Ken maar voeg dan standaardwaarden toe:

function load(context) {
    var defaults = {
        parameter1: defaultValue1,
        parameter2: defaultValue2,
        ...
    };
    var context = extend(defaults, context);
    // do stuff
}

Op deze manier kun je, als je veel parameters hebt, maar deze niet per se bij elke aanroep van de functie hoeft in te stellen, gewoon de niet-standaardinstellingen specificeren. Voor de extend-methode kunt u de extend-methode van jQuery ($.extend()) gebruiken, uw eigen methode maken of het volgende gebruiken:

function extend() {
    for (var i = 1; i < arguments.length; i++)
        for (var key in arguments[i])
            if (arguments[i].hasOwnProperty(key))
                arguments[0][key] = arguments[i][key];
    return arguments[0];
}

Hierdoor wordt het contextobject samengevoegd met de standaardwaarden en worden eventuele niet-gedefinieerde waarden in uw object met de standaardwaarden ingevuld.


Antwoord 5, autoriteit 2%

Het verdient de voorkeur om de syntaxis van de restparameter te gebruiken, zoals Ramast aangaf.

function (a, b, ...args) {}

Ik wil gewoon een mooie eigenschap van het argument …args toevoegen

  1. Het is een array en geen object zoals argumenten. Dit stelt je in staat om functies zoals kaart toe te passen of direct te sorteren.
  2. Het bevat niet alle parameters, maar alleen de parameters die er vanaf worden doorgegeven. bijv. functie (a, b, …args) in dit geval bevat args
    argument 3 tot argumenten.length

Antwoord 6, autoriteit 2%

Ja, gewoon zo:

function load()
{
  var var0 = arguments[0];
  var var1 = arguments[1];
}
load(1,2);

Antwoord 7, autoriteit 2%

Zoals reeds vermeld, kunt u het object argumentsgebruiken om een ​​variabel aantal functieparameters op te halen.

Als je een andere functie met dezelfde argumenten wilt aanroepen, gebruik dan apply. U kunt zelfs argumenten toevoegen of verwijderen door argumentsom te zetten in een array. Deze functie voegt bijvoorbeeld wat tekst in voordat wordt ingelogd op de console:

log() {
    let args = Array.prototype.slice.call(arguments);
    args = ['MyObjectName', this.id_].concat(args);
    console.log.apply(console, args);
}

Antwoord 8

Hoewel ik het er in het algemeen mee eens ben dat de benoemde argumenten-benadering nuttig en flexibel is (tenzij je om de volgorde geeft, in welk geval argumenten het gemakkelijkst zijn), maak ik me wel zorgen over de kosten van de mbeasley-benadering (met gebruik van standaardinstellingen en uitbreidingen). Dit zijn extreem hoge kosten voor het ophalen van standaardwaarden. Eerst worden de standaardwaarden binnen de functie gedefinieerd, zodat ze bij elke aanroep opnieuw worden ingevuld. Ten tweede kunt u eenvoudig de genoemde waarden uitlezen en tegelijkertijd de standaardwaarden instellen met ||. Het is niet nodig om nog een nieuw object te maken en samen te voegen om deze informatie te krijgen.

function load(context) {
   var parameter1 = context.parameter1 || defaultValue1,
       parameter2 = context.parameter2 || defaultValue2;
   // do stuff
}

Dit is ongeveer dezelfde hoeveelheid code (misschien iets meer), maar zou een fractie van de runtime-kosten moeten zijn.


Antwoord 9

Terwijl @roufamatic het gebruik van het sleutelwoord argumenten liet zien en @Ken een geweldig voorbeeld van een gebruiksobject liet zien, voel ik me niet echt aangesproken op wat er in dit geval aan de hand is en kan toekomstige lezers in verwarring brengen of een slechte gewoonte inboezemen als niet expliciet het vermelden van een functie/methode is bedoeld om een ​​variabel aantal argumenten/parameters op te nemen.

function varyArg () {
    return arguments[0] + arguments[1];
}

Als een andere ontwikkelaar uw code doorkijkt, is het heel gemakkelijk om aan te nemen dat deze functie geen parameters nodig heeft. Vooral als die ontwikkelaar niet bekend is met het zoekwoord argumenten. Daarom is het een goed idee om een ​​stijlrichtlijn te volgen en consistent te zijn. Ik zal die van Google gebruiken voor alle voorbeelden.

Laten we expliciet stellen dat dezelfde functie variabele parameters heeft:

function varyArg (var_args) {
    return arguments[0] + arguments[1];
}

Objectparameter VS var_args

Er kunnen momenten zijn waarop een object nodig is, aangezien dit de enige goedgekeurde en weloverwogen best practice-methode van een datamap is. Associatieve arrays worden afgekeurd en ontmoedigd.

SIDENOTE:het trefwoord argumenten retourneert in feite een object met getallen als sleutel. De prototypische overerving is ook de objectfamilie. Zie einde van antwoord voor correct arraygebruik in JS

In dit geval kunnen we dit ook expliciet aangeven. Opmerking: deze naamgevingsconventie wordt niet geleverd door Google, maar is een voorbeeld van een expliciete declaratie van het type param. Dit is belangrijk als u op zoek bent naar een strikter getypt patroon in uw code.

function varyArg (args_obj) {
    return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});

Welke te kiezen?

Dit hangt af van de behoeften van uw functie en programma. Als u bijvoorbeeld eenvoudigweg een waardebasis wilt retourneren op een iteratief proces voor alle doorgegeven argumenten, blijf dan zeker bij het trefwoord argumenten. Als u definitie van uw argumenten en het in kaart brengen van de gegevens nodig hebt, dan is de objectmethode de juiste keuze. Laten we twee voorbeelden bekijken en dan zijn we klaar!

Gebruik van argumenten

function sumOfAll (var_args) {
    return arguments.reduce(function(a, b) {
        return a + b;
    }, 0);
}
sumOfAll(1,2,3); // returns 6

Objectgebruik

function myObjArgs(args_obj) {
    // MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
    if (typeof args_obj !== "object") {
        return "Arguments passed must be in object form!";
    }
    return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old

Toegang tot een array in plaats van een object (“…args” De rest-parameter)

Zoals bovenaan het antwoord vermeld, retourneert het sleutelwoord argumentenfeitelijk een object. Daarom moet elke methode die u voor een array wilt gebruiken, worden aangeroepen. Een voorbeeld hiervan:

Array.prototype.map.call(arguments, function (val, idx, arr) {});

Gebruik de rest-parameter om dit te voorkomen:

function varyArgArr (...var_args) {
    return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5

Antwoord 10

Gebruik het object argumentswanneer u zich in de functie bevindt om toegang te krijgen tot alle doorgegeven argumenten.


Antwoord 11

Houd er rekening mee dat het doorgeven van een object met benoemde eigenschappen, zoals Ken voorstelde, de kosten van het toewijzen en vrijgeven van het tijdelijke object aan elke oproep toevoegt. Het doorgeven van normale argumenten op waarde of verwijzing is over het algemeen het meest efficiënt. Voor veel toepassingen zijn de prestaties echter niet kritiek, maar voor sommige wel.


Antwoord 12

Gebruik array en dan kun je gebruiken hoeveel parameters je nodig hebt. Bereken bijvoorbeeld het gemiddelde van het aantal elementen van een array:

function fncAverage(sample) {
    var lenghtSample = sample.length;
    var elementsSum = 0;
    for (var i = 0; i < lenghtSample; i++) {
        elementsSum = Number(elementsSum) + Number(sample[i]);
    }
    average = elementsSum / lenghtSample
    return (average);
}
console.log(fncAverage([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // results 5.5
let mySample = [10, 20, 30, 40];
console.log(fncAverage(mySample)); // results 25
//try your own arrays of numbers

Other episodes