Mehrere Werte in JavaScript zurückgeben?

846

Ich versuche, zwei Werte in JavaScript zurückzugeben . Ist das möglich?

var newCodes = function() {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return dCodes, dCodes2;
};
Asim Zaidi
quelle
Sie können dies mithilfe von Rückrufen lösen. Wenn Sie dazu bereit sind, lesen Sie meine Antwort. Die Leute vergessen, dass Sie mit JS einfach "mehrere Werte zurückgeben" können, indem Sie Tupel oder sogar Rückrufe verwenden!
Alexander Mills
16
Die Antworten sind veraltet. Es ist jetzt möglich. 2ality.com/2014/06/es6-multiple-return-values.html
Erel Segal-Halevi
3
Sie geben technisch immer noch ein einzelnes Objekt / Array zurück. Es ist nur die Dekonstruktion, die in ES6 einfacher ist.
Andrea Bergonzo

Antworten:

1298

Nein, aber Sie können ein Array zurückgeben, das Ihre Werte enthält:

function getValues() {
    return [getFirstValue(), getSecondValue()];
}

Dann können Sie wie folgt darauf zugreifen:

var values = getValues();
var first = values[0];
var second = values[1];

Mit der neuesten ECMAScript 6-Syntax * können Sie den Rückgabewert auch intuitiver destruieren:

const [first, second] = getValues();

Wenn Sie jedem der zurückgegebenen Werte "Beschriftungen" hinzufügen möchten (einfacher zu pflegen), können Sie ein Objekt zurückgeben:

function getValues() {
    return {
        first: getFirstValue(),
        second: getSecondValue(),
    };
}

Und um darauf zuzugreifen:

var values = getValues();
var first = values.first;
var second = values.second;

Oder mit ES6-Syntax:

const {first, second} = getValues();

* In dieser Tabelle finden Sie Informationen zur Browserkompatibilität. Grundsätzlich unterstützen alle modernen Browser außer IE diese Syntax, aber Sie können ES6-Code zur Build-Zeit mit Tools wie Babel bis zu IE-kompatiblem JavaScript kompilieren .

Sasha Chedygov
quelle
151
Oder Sie können ein Objekt zurückgeben return {dCodes : dCodes, dCodes2 : dCodes2};, um die Referenzierung zu vereinfachen.
Intelekshual
10
Sie können sogar ein Objekt {: dCodes: dCodes, dCodes2: dCodes2} funktional gleich zurückgeben, aber wenn Sie auf Ihr zurückgegebenes Objekt verweisen, haben Sie einen etwas besser lesbaren Code als obj.dCodes und obj.dCodes2 vs obj [0] und obj [1 ]
Jonathan S.
1
@alexela Sicher können Sie einfach var dCodes = newCodes () verwenden. dCodes; var dCodes2 = newCodes (). dCodes2 Sie werden die Funktion jedoch zweimal aufrufen, was bei Komplexität eine Verschwendung von Ressourcen sein kann.
Vadim Kirilchuk
12
@VadimKirilchuk Keine Notwendigkeit, es zweimal mit Destrukturierungsauftrag aufzurufen - z. const { dCodes, dCodes2 } = newCodes();
Taylor Edmiston
7
Wie andere Antworten sagten (und Kommentare implizierten), bietet ES6 hier einige Optionen. 3 um genau zu sein: (1) Kurzform return {dCodes, dCodes2} der Objekteigenschaften funktioniert genauso wie @Intelekshual und (2) mit derselben Funktion können Sie einfach mit destrukturierenden Arrays [dCodes, dCodes2] = newCodes()oder (3) Objekten darauf zugreifen ({dCodes, dCodes2} = newCodes())(dort muss keine Deklaration verwendet werden @Taylor) , obwohl a varfür das aktuelle Beispiel von Sasha passender wäre).
Cregox
241

Sie können dies ab Javascript 1.7 mit "Destructuring Assignments" tun . Beachten Sie, dass diese in älteren Javascript-Versionen nicht verfügbar sind (dh - weder in der 3. noch in der 5. Ausgabe von ECMAScript).

Sie können 1+ Variablen gleichzeitig zuweisen:

var [x, y] = [1, 2];
x; // 1
y; // 2

// or

[x, y] = (function(){ return [3, 4]; })();
x; // 3
y; // 4

Sie können auch die Objektzerstörung in Kombination mit der Kurzform des Eigenschaftswerts verwenden , um die Rückgabewerte in einem Objekt zu benennen und die gewünschten auszuwählen:

let {baz, foo} = (function(){ return {foo: 3, bar: 500, baz: 40} })();
baz; // 40
foo; // 3

Lassen Sie sich übrigens nicht von der Tatsache täuschen, dass ECMAScript dies ermöglicht return 1, 2, .... Was dort wirklich passiert, ist nicht das, was scheinen mag. Ein Ausdruck in return - Anweisung - 1, 2, 3- ist nichts anderes als ein Komma - Operator auf Zahlenliterale angewendet ( 1, 2, und 3) der Reihe nach , die schließlich auf den Wert des letzten Ausdrucks auswertet - 3. Deshalb return 1, 2, 3ist funktional identisch mit nichts anderem als return 3.

return 1, 2, 3;
// becomes
return 2, 3;
// becomes
return 3;
Kangax
quelle
1
Seltsame und interessante Sache über das letzte Beispiel: für ein function foo(){return 1,2,3;}Tun console.log([].push(foo()))druckt 1.
Meredith
@ AurélienOoms habe ich später realisiert. Danke
Meredith
1
warum var [x, y] = [1, 2]; x; // 1 y; // 2 funktioniert das nicht in chrom? einen Fehler auslösen; ReferenceError: Ungültige linke Seite in Zuordnung
Naveen Agarwal
1
Chrome v49 wurde vor einer Woche veröffentlicht und unterstützt sofort "Destrukturierungsaufgaben".
Eugene Kulabuhov
1
Dies sollte die akzeptierte Antwort sein - die neue Destrukturierung ist eine großartige Möglichkeit, dies zu tun.
Jez
68

Geben Sie einfach ein Objektliteral zurück

function newCodes(){
    var dCodes = fg.codecsCodes.rs; // Linked ICDs  
    var dCodes2 = fg.codecsCodes2.rs; //Linked CPTs       
    return {
        dCodes: dCodes, 
        dCodes2: dCodes2
    };  
}


var result = newCodes();
alert(result.dCodes);
alert(result.dCodes2);
Sean Kinsey
quelle
@ SeanKinsey Ich mag diese Lösung. Es kann für mich nützlich sein. Eine Frage: Sollte bei der Rückgabe eine Funktion erforderlich sein, würde jede Instanz von result ( result1 .. resultN ) eine eigene Kopie der Funktion erhalten oder würde der Funktionscode wiederverwendet? (Ich weiß nicht, wie ich das testen könnte.) TIA.
Karl
44

Seit ES6 können Sie dies tun

let newCodes = function() {  
    const dCodes = fg.codecsCodes.rs
    const dCodes2 = fg.codecsCodes2.rs
    return {dCodes, dCodes2}
};

let {dCodes, dCodes2} = newCodes()

Der Rückgabeausdruck {dCodes, dCodes2}ist eine Kurzform des Eigenschaftswerts und entspricht dieser {dCodes: dCodes, dCodes2: dCodes2}.

Diese Zuordnung in der letzten Zeile wird als Objektzerstörungszuweisung bezeichnet . Es extrahiert den Eigenschaftswert eines Objekts und weist ihn einer gleichnamigen Variablen zu. Wenn Sie Variablen mit unterschiedlichen Namen Rückgabewerte zuweisen möchten, können Sie dies folgendermaßen tunlet {dCodes: x, dCodes2: y} = newCodes()

Peracek
quelle
27

Ecmascript 6 enthält "Destrukturierungszuweisungen" (wie von Kangax erwähnt), sodass Sie in allen Browsern (nicht nur in Firefox) ein Array von Werten erfassen können, ohne ein benanntes Array oder Objekt zum alleinigen Zweck der Erfassung erstellen zu müssen.

//so to capture from this function
function myfunction()
{
 var n=0;var s=1;var w=2;var e=3;
 return [n,s,w,e];
}

//instead of having to make a named array or object like this
var IexistJusttoCapture = new Array();
IexistJusttoCapture = myfunction();
north=IexistJusttoCapture[0];
south=IexistJusttoCapture[1];
west=IexistJusttoCapture[2];
east=IexistJusttoCapture[3];

//you'll be able to just do this
[north, south, west, east] = myfunction(); 

Sie können es bereits in Firefox ausprobieren!

user3015682
quelle
24

Eine weitere erwähnenswerte (ES6) Syntax ist die Verwendung der Kurzform zur Objekterstellung zusätzlich zur Zerstörung der Zuweisung.

function fun1() {
  var x = 'a';
  var y = 'b';
  return { x, y, z: 'c' };
  // literally means { x: x, y: y, z: 'c' };
}

var { z, x, y } = fun1(); // order or full presence is not really important
// literally means var r = fun1(), x = r.x, y = r.y, z = r.z;
console.log(x, y, z);

Diese Syntax kann mit babel oder einem anderen js-Polyfüller für ältere Browser polygefüllt werden, funktioniert aber glücklicherweise jetzt nativ mit den neuesten Versionen von Chrome und Firefox.

Da beim Erstellen eines neuen Objekts jedoch die Speicherzuweisung (und die eventuelle GC-Auslastung) eine Rolle spielen, sollten Sie nicht viel Leistung davon erwarten. JavaScript ist sowieso nicht die beste Sprache, um hochoptimale Dinge zu entwickeln. Wenn dies jedoch erforderlich ist, können Sie Ihr Ergebnis auf ein umgebendes Objekt oder solche Techniken übertragen, die normalerweise übliche Leistungstricks zwischen JavaScript, Java und anderen Sprachen sind.

Ebrahim Byagowi
quelle
Das funktioniert noch nicht auf IE oder Edge, wollte nur beachten.
user1133275
Ich habe dies ziemlich oft verwendet ... es ist schneller / reibungsloser, ein Array zu verwenden und das Erstellen eines Objekts nach Möglichkeit zu vermeiden, wie von @ user3015682 gezeigt.
Dkloke
18

Der beste Weg dafür ist

function a(){
     var d=2;
     var c=3;
     var f=4;
     return {d:d,c:c,f:f}
}

Dann benutze

a().f

Rückkehr 4

In ES6 können Sie diesen Code verwenden

function a(){
      var d=2;
      var c=3;
      var f=4;
      return {d,c,f}
}
Behnam Mohammadi
quelle
Führen Sie dann die Funktion für jede Variable erneut aus? Das ist nicht der beste Ansatz.
Elia Iliashenko
Diese Funktion gibt einen Mehrfachwert zurück und ist möglicherweise nicht der beste Ansatz.
Behnam Mohammadi
Jedes Mal, wenn der Interpreter a () trifft, führt er die Funktion erneut aus. Also, var f = a (). F; var c = a (). c; var d = a (). d; startet dreimal ein (), was zu Leistungseinbußen führen kann. Der bessere Ansatz wäre var result = a (); var f = result.f; usw.
Elia Iliashenko
1
OK für eine bessere Leistung können Sie den Wert einer Variablen beibehalten und verwenden, z. B. var result = a (); und verwenden Sie den Wert result.d oder result.c und result.f, also führen Sie nur einmal eine () -Funktion aus.
Behnam Mohammadi
9

Neben der Rückgabe eines Arrays oder eines Objekts, wie von anderen empfohlen, können Sie auch eine Collector-Funktion verwenden (ähnlich der in The Little Schemer ):

function a(collector){
  collector(12,13);
}

var x,y;
a(function(a,b){
  x=a;
  y=b;
});

Ich habe einen jsperf-Test durchgeführt, um festzustellen, welche der drei Methoden schneller ist. Das Array ist am schnellsten und der Kollektor am langsamsten.

http://jsperf.com/returning-multiple-values-2

Zelenova
quelle
In der Regel collectorheißt continuationund die Technik heißt CPS
bis
7

In JS können wir leicht ein Tupel mit einem Array oder Objekt zurückgeben, aber nicht vergessen! => JS ist eine callbackorientierte Sprache, und hier gibt es ein kleines Geheimnis für die "Rückgabe mehrerer Werte", das noch niemand erwähnt hat. Versuchen Sie Folgendes:

var newCodes = function() {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return dCodes, dCodes2;
};

wird

var newCodes = function(fg, cb) {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    cb(null, dCodes, dCodes2);
};

:) :)

bam! Dies ist einfach eine andere Möglichkeit, Ihr Problem zu lösen.

Alexander Mills
quelle
6

Hinzufügen der fehlenden wichtigen Teile, um diese Frage zu einer vollständigen Ressource zu machen, da dies in den Suchergebnissen angezeigt wird.

Objektzerstörung

Bei der Objektzerstörung müssen Sie nicht unbedingt denselben Schlüsselwert wie Ihren Variablennamen verwenden. Sie können einen anderen Variablennamen zuweisen, indem Sie ihn wie folgt definieren:

const newCodes = () => {  
    let dCodes = fg.codecsCodes.rs;
    let dCodes2 = fg.codecsCodes2.rs;
    return { dCodes, dCodes2 };
};

//destructuring
let { dCodes: code1, dCodes2: code2 } = newCodes();

//now it can be accessed by code1 & code2
console.log(code1, code2);

Array-Destrukturierung

Bei der Array-Destrukturierung können Sie die nicht benötigten Werte überspringen.

const newCodes = () => {  
    //...
    return [ dCodes, dCodes2, dCodes3 ];
};

let [ code1, code2 ] = newCodes(); //first two items
let [ code1, ,code3 ] = newCodes(); //skip middle item, get first & last
let [ ,, code3 ] = newCodes(); //skip first two items, get last
let [ code1, ...rest ] = newCodes(); //first item, and others as an array

Es ist erwähnenswert, dass dies ...restimmer am Ende sein sollte, da es keinen Sinn macht, etwas zu zerstören, nachdem alles andere zusammengefasst wurde rest.

Ich hoffe, dass dies dieser Frage einen Mehrwert verleiht :)

Nimeshka Srimal
quelle
5

Sie können auch tun:

function a(){
  var d=2;
  var c=3;
  var f=4;
  return {d:d,c:c,f:f}
}

const {d,c,f} = a()
Joris Mans
quelle
5

Eine sehr häufige Art und Weise zu mehr Werte zurückgeben in JavaScript ist unter Verwendung eines Objektliterale , so etwas wie:

const myFunction = () => {
  const firstName = "Alireza", 
        familyName = "Dezfoolian",
        age = 35;
  return { firstName, familyName, age};
}

und erhalten Sie die Werte wie folgt:

myFunction().firstName; //Alireza
myFunction().familyName; //Dezfoolian
myFunction().age; //age

oder noch kürzer:

const {firstName, familyName, age} = myFunction();

und bekommen sie individuell wie:

firstName; //Alireza
familyName; //Dezfoolian
age; //35
Alireza
quelle
4

Sie können "Objekt" verwenden

function newCodes(){
    var obj= new Object();
    obj.dCodes = fg.codecsCodes.rs;
    obj.dCodes2 = fg.codecsCodes2.rs;

    return obj;
}
sebu
quelle
1
Dies ist der richtige Weg für IE. Später verwenden wie: let obj = newCodes (); alert (obj.dCodes);
Asen Kasimov
3

Alles ist richtig. returnverarbeitet logisch von links nach rechts und gibt den letzten Wert zurück.

function foo(){
    return 1,2,3;
}

>> foo()
>> 3
Artemii
quelle
1
Das ,ist ein Operator und kann in jedem Ausdruck verwendet werden. Hier ist nichts Besonderes return.
Gman
3

Ich würde vorschlagen, die neueste Destrukturierungsaufgabe zu verwenden (aber stellen Sie sicher, dass sie in Ihrer Umgebung unterstützt wird ).

var newCodes = function () {
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return {firstCodes: dCodes, secondCodes: dCodes2};
};
var {firstCodes, secondCodes} = newCodes()
AMTourky
quelle
2

Ich kenne zwei Möglichkeiten, dies zu tun: 1. Als Array zurückgeben 2. Als Objekt zurückgeben

Hier ist ein Beispiel, das ich gefunden habe:

<script>
// Defining function
function divideNumbers(dividend, divisor){
    var quotient = dividend / divisor;
    var arr = [dividend, divisor, quotient];
    return arr;
}

// Store returned value in a variable
var all = divideNumbers(10, 2);

// Displaying individual values
alert(all[0]); // 0utputs: 10
alert(all[1]); // 0utputs: 2
alert(all[2]); // 0utputs: 5
</script>



<script>
// Defining function
function divideNumbers(dividend, divisor){
    var quotient = dividend / divisor;
    var obj = {
        dividend: dividend,
        divisor: divisor,
        quotient: quotient
    };
    return obj;
}

// Store returned value in a variable
var all = divideNumbers(10, 2);

// Displaying individual values
alert(all.dividend); // 0utputs: 10
alert(all.divisor); // 0utputs: 2
alert(all.quotient); // 0utputs: 5
</script>
Kallol Medhi
quelle
1

Vor ein paar Tagen hatte ich die ähnliche Anforderung, mehrere Rückgabewerte von einer von mir erstellten Funktion zu erhalten.

Von vielen Rückgabewerten brauchte ich es, um nur einen bestimmten Wert für eine gegebene Bedingung und dann einen anderen Rückgabewert zurückzugeben, der einer anderen Bedingung entspricht.


Hier ist das Beispiel, wie ich das gemacht habe:

Funktion:

function myTodayDate(){
    var today = new Date();
    var day = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
    var month = ["January","February","March","April","May","June","July","August","September","October","November","December"];
    var myTodayObj = 
    {
        myDate : today.getDate(),
        myDay : day[today.getDay()],
        myMonth : month[today.getMonth()],
        year : today.getFullYear()
    }
    return myTodayObj;
}

Erforderlichen Rückgabewert von Objekt abrufen, das von der Funktion zurückgegeben wird:

var todayDate = myTodayDate().myDate;
var todayDay = myTodayDate().myDay;
var todayMonth = myTodayDate().myMonth;
var todayYear = myTodayDate().year;

Der springende Punkt bei der Beantwortung dieser Frage ist, diesen Ansatz zu teilen, um Date in einem guten Format zu erhalten. Hoffe es hat dir geholfen :)

krupesh Anadkat
quelle
1

Ich füge hier nichts Neues hinzu, als einen anderen alternativen Weg.

 var newCodes = function() {
     var dCodes = fg.codecsCodes.rs;
     var dCodes2 = fg.codecsCodes2.rs;
     let [...val] = [dCodes,dCodes2];
     return [...val];
 };
Kumar
quelle
0

Nun, wir können nicht genau das tun, was Sie versuchen. Aber etwas, das wahrscheinlich unten liegt, kann getan werden.

function multiReturnValues(){
    return {x:10,y:20};
}

Dann beim Aufruf der Methode

const {x,y} = multiReturnValues();

console.log(x) ---> 10
console.log(y) ---> 20
Anjana
quelle