JavaScriptで複数の値を返しますか?


846

JavaScriptで 2つの値を返そうとしています。これは可能ですか?

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

コールバックを使用してこれを解決できます。そうする意思がある場合は、私の答えを参照してください。JSを使用すると、タプルやコールバックを使用するだけで簡単に「複数の値を返す」ことができることを人々は忘れます。
Alexander Mills

16
答えは古くなっています。今では可能です。2ality.com/2014/06/es6-multiple-return-values.html
Segal-Halevi

3
あなたは技術的にはまだ単一のオブジェクト/配列を返しています。それはES6でより簡単なのは単に分解です。
Andrea Bergonzo

回答:


1298

いいえ。ただし、値を含む配列を返すことができます。

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

その後、次のようにアクセスできます。

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

最新のECMAScript 6構文 *を使用すると、戻り値をより直感的に分解することもできます。

const [first, second] = getValues();

戻り値のそれぞれに「ラベル」を付けたい場合(維持しやすい)、オブジェクトを返すことができます。

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

そしてそれらにアクセスするには:

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

またはES6構文を使用:

const {first, second} = getValues();

* ブラウザの互換性については、この表を参照してください。基本的に、IEを除くすべての最新のブラウザーはこの構文をサポートしていますが、ビルド時にBabelなどのツールを使用してES6コードをIE互換のJavaScriptにコンパイルできます。


151
または、オブジェクトを返すこともできreturn {dCodes : dCodes, dCodes2 : dCodes2};ます。参照しやすくするためです。
Intelekshual、

10
機能的に同じオブジェクト{:dCodes:dCodes、dCodes2:dCodes2}を返すことさえできますが、返されたオブジェクトを参照すると、obj.dCodesとobj.dCodes2対obj [0]とobj [1 ]
ジョナサンS.

1
@alexela確かに単にvar dCodes = newCodes()。dCodes;を使用できます。var dCodes2 = newCodes()。dCodes2ただし、関数を2回呼び出すため、複雑な場合はリソースの浪費になる可能性があります。
Vadim Kirilchuk 2016

12
@VadimKirilchuk構造化割り当てで2回呼び出す必要はありません—例:const { dCodes, dCodes2 } = newCodes();
テイラーエドミストン2017年

7
他の回答が言うように(そしてコメントが暗示するように)、ES6はここにいくつかのオプションをもたらします。3正確には:(1)オブジェクトプロパティの省略表現 return {dCodes, dCodes2}は、前述の@Intelekshualとまったく同じように機能し、(2)同じ関数を使用して、配列を破壊することで簡単にアクセスできます[dCodes, dCodes2] = newCodes()(3)オブジェクト({dCodes, dCodes2} = newCodes())(そこで宣言を使用する必要はありません@Taylorただし、a varは現在のSashaの例により適しています)。
cregox

241

JavaScript 1.7以降では、「割り当ての分解」を使用してこれを行うことができます。これらは古いJavaScriptバージョンでは使用できないことに注意してください(つまり、ECMAScriptの第3版と第5版のどちらでも)。

1つ以上の変数を同時に割り当てることができます。

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

// or

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

プロパティ値の省略表現組み合わせたオブジェクトのデストラチャリングを使用して、オブジェクトの戻り値に名前を付け、必要なものを選択することもできます。

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

ちなみに、ECMAScriptで許可されているという事実に騙されないでくださいreturn 1, 2, ...。実際に起こることは、見た目ではありません。return文の式は- 1, 2, 3-何もなく、コンマ演算子は(数値リテラルに適用されていない123-最終的にはその最後の式の値に評価され、順次)3。そのためreturn 1, 2, 3、機能的にはと同じですreturn 3

return 1, 2, 3;
// becomes
return 2, 3;
// becomes
return 3;

1
最後の例についての奇妙で興味深いこと:function foo(){return 1,2,3;}実行中のconsole.log([].push(foo()))出力1.
Meredith

@AurélienOoms後で気づきました。ありがとう
メレディス

1
なぜvar [x、y] = [1、2]; バツ; // 1年; // 2これはクロムでは機能しませんか?エラーを発生させます。ReferenceError:割り当ての無効な左側
Naveen Agarwal 14年

1
Chrome v49は、1週間前にリリースされ、「デストラクタ割り当て」をそのままサポートします。
Eugene Kulabuhov 2016年

1
これは受け入れられる答えであるはずです-新しい破壊はこれを行うための素晴らしい方法です。
Jez

68

オブジェクトリテラルを返すだけです

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);

@SeanKinseyこのソリューションが好きです。それは私にとって便利かもしれません。1つの質問、戻り値に関数が必要な場合、resultresult1 .. resultN)のすべてのインスタンスが関数の独自のコピーを取得するか、または関数コードの再利用があるか?(これをどのようにテストできるかわかりません。)TIA。
Karl

44

ES6以降、これを行うことができます

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

let {dCodes, dCodes2} = newCodes()

戻り式{dCodes, dCodes2}プロパティ値の省略形であり、これと同等です{dCodes: dCodes, dCodes2: dCodes2}です。

最終行のこの割り当ては、オブジェクト破棄割り当てと呼ばれます。オブジェクトのプロパティ値を抽出し、同じ名前の変数に割り当てます。別の名前の変数に戻り値を割り当てる場合は、次のようにすることができますlet {dCodes: x, dCodes2: y} = newCodes()


27

Ecmascript 6には「破壊的な割り当て」(kangaxについて言及)が含まれているため、Firefoxだけでなく、すべてのブラウザーで値の配列をキャプチャできます。名前の付いた配列やオブジェクトを作成するだけで、それらをキャプチャすることができます。

//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(); 

あなたはすでにFirefoxでそれを試すことができます!


24

新しく導入された(ES6)構文についてもう1つ言及する価値があるのは、割り当てを破棄することに加えて、オブジェクト作成の省略表現を使用することです。

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);

この構文は、古いブラウザではbabelまたは他のjsポリフィラーでポリフィルすることができますが、幸いなことに、最近のバージョンのChromeおよびFirefoxでネイティブに動作します。

しかし、新しいオブジェクトを作成するとき、メモリ割り当て(および最終的なGC負荷)がここに含まれるので、そこから多くのパフォーマンスを期待しないでください。JavaScriptは、とにかく非常に最適なものを開発するのに最適な言語ではありませんが、それが必要な場合は、JavaScript、Java、および他の言語間で通常一般的なパフォーマンストリックである周囲のオブジェクトまたはそのような手法に結果を置くことを検討できます。


これはIEまたはEdgeではまだ機能していません。注意してください。
user1133275 2017年

これをかなり使用しています... @ user3015682で示されているように、配列を使用し、可能であればオブジェクトの作成を避ける方が高速で滑らかです。
dkloke 2017

18

これのための最良の方法は

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

次に使用します

a().f

リターン4

ES6ではこのコードを使用できます

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

次に、各変数に対して関数を再度実行しますか?それは最善の方法ではありません。
エリアイリアシェンコ2015年

この関数は複数の値を返すため、おそらく最善の方法ではありません。
Behnam Mohammadi 2015

インタプリタがa()に出会うたびに、関数を再度実行します。したがって、var f = a()。f; var c = a()。c; var d = a()。d; a()を3回起動しますが、パフォーマンスが低下する傾向があります。より良いアプローチは、var result = a();です。var f = result.f; その他
エリアイリアシェンコ2015年

1
パフォーマンスを向上させるために、変数の値を保持して使用することができます。例:var result = a(); そして、値result.dまたはresult.cおよびresult.fを使用するので、一度にa()関数を実行します。
Behnam Mohammadi、2015

9

他の人が推奨しているように配列またはオブジェクトを返す以外に、コレクター関数を使用することもできます(The Little Schemerにあるものと同様)。

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

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

私はjsperfテストを行って、3つの方法のうちどれが速いかを確認しました。アレイが最も速く、コレクターが最も遅い。

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


一般的にcollector呼ばれているcontinuationと技術が呼ばれているCPS
ceving

7

JSでは、配列またはオブジェクトを含むタプルを簡単に返すことができますが、忘れないでください。=> JSはcallback指向的な言語であり、「複数の値を返す」ことについて、まだ誰も言及していない小さな秘密があります。これを試してください。

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

なる

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

:)

バム!これは単に問題を解決する別の方法です。


6

欠落している重要な部分を追加して、この質問を完全なリソースにします。これは検索結果に表示されるためです。

オブジェクトの破壊

オブジェクトの構造化では、必ずしも変数名と同じキー値を使用する必要はありません。次のように定義することで、異なる変数名を割り当てることができます。

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);

配列の破壊

配列の非構造化では、不要な値をスキップできます。

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

...rest他のすべてがに集約された後、何かを破壊することは意味をなさないので、常に最後にあることに注意する価値がありrestます。

これがこの質問にいくつかの価値を追加することを願っています:)



5

JavaScriptで複数の値返す非常に一般的な方法は、次のようなオブジェクトリテラルを使用することです。

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

次のような値を取得します。

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

またはさらに短い方法:

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

次のように個別に取得します。

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

4

「オブジェクト」を使用できます

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

    return obj;
}

1
これがIEへの道です。後で次のように使用します:let obj = newCodes(); alert(obj.dCodes);
Asen Kasimov

3

すべて正解です。return左から右に論理的に処理し、最後の値を返します。

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

>> foo()
>> 3

1
これ,は演算子であり、任意の式で使用できます。returnここで特別なことは何もありません。
gman 2017


2

私はこれを行う2つの方法を知っています:1.配列として返す2.オブジェクトとして返す

これが私が見つけた例です:

<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>

1

数日前、私が作成した関数から複数の戻り値を取得するという同様の要件がありました。

多くの戻り値から、特定の条件の特定の値のみを返し、次に他の条件に対応する他の戻り値を返す必要がありました。


これが私がそれをした方法の例です:

関数:

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;
}

関数から返されたオブジェクトから必要な戻り値を取得しています:

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

この質問に答える全体のポイントは、日付を適切な形式で取得するこのアプローチを共有することです。それがあなたのお役に立てば幸いです:)


1

私はここで新しく追加するものではなく、別の代替方法です。

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

0

まあ私たちはあなたの試みを正確に行うことはできません。ただし、以下の可能性があります。

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

次に、メソッドを呼び出すとき

const {x,y} = multiReturnValues();

console.log(x) ---> 10
console.log(y) ---> 20
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.