Kembalikan beberapa nilai dalam JavaScript?

846

Saya mencoba mengembalikan dua nilai dalam JavaScript . Apakah ini mungkin?

var newCodes = function() {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return dCodes, dCodes2;
};
Asim Zaidi
sumber
Anda dapat menyelesaikan ini dengan menggunakan panggilan balik, jika Anda bersedia melakukannya, lihat jawaban saya. Orang-orang lupa bahwa Anda dapat "mengembalikan beberapa nilai" dengan mudah menggunakan JS, menggunakan tuple atau bahkan: callback!
Alexander Mills
16
Jawabannya sudah usang. Sekarang mungkin. 2ality.com/2014/06/es6-multiple-return-values.html
Erel Segal-Halevi
3
Anda secara teknis masih mengembalikan satu objek / array, itu hanya dekonstruksi yang lebih sederhana di ES6.
Andrea Bergonzo

Jawaban:

1299

Tidak, tetapi Anda bisa mengembalikan array yang mengandung nilai-nilai Anda:

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

Maka Anda dapat mengaksesnya seperti:

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

Dengan sintaks ECMAScript 6 * terbaru, Anda juga dapat merusak nilai pengembalian secara lebih intuitif:

const [first, second] = getValues();

Jika Anda ingin meletakkan "label" pada masing-masing nilai yang dikembalikan (lebih mudah untuk dipelihara), Anda dapat mengembalikan objek:

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

Dan untuk mengaksesnya:

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

Atau dengan sintaks ES6:

const {first, second} = getValues();

* Lihat tabel ini untuk kompatibilitas browser. Pada dasarnya, semua browser modern selain dari IE mendukung sintaks ini, tetapi Anda dapat mengkompilasi kode ES6 ke JavaScript yang kompatibel dengan IE saat membuat dengan alat-alat seperti Babel .

Sasha Chedygov
sumber
151
Atau Anda dapat mengembalikan objek: return {dCodes : dCodes, dCodes2 : dCodes2};untuk memudahkan referensi.
Intelekshual
10
Anda bahkan dapat mengembalikan objek {: dCodes: dCodes, dCodes2: dCodes2} secara fungsional sama tetapi ketika Anda mereferensikan objek Anda yang dikembalikan, Anda memiliki kode yang sedikit lebih mudah dibaca sebagai obj.dCodes dan obj.dCodes2 vs obj [0] dan obj [1] ]
Jonathan S.
1
@alexela Tentu Anda cukup menggunakan var dCodes = newCodes (). dCodes; var dCodes2 = newCodes (). dCodes2 Namun, Anda akan memanggil fungsi dua kali yang mungkin membuang-buang sumber daya jika kompleks.
Vadim Kirilchuk
12
@VadimKirilchuk Tidak perlu menyebutnya dua kali dengan penugasan yang merusak - mis. const { dCodes, dCodes2 } = newCodes();
Taylor Edmiston
7
seperti jawaban lain katakan (dan komentar tersirat), ES6 membawa beberapa opsi di sini. 3 tepatnya: (1) singkatan properti objek return {dCodes, dCodes2} bekerja sama persis dengan @Intelekshual yang disebutkan dan (2) menggunakan fungsi yang sama Anda dapat mengaksesnya dengan array yang merusak [dCodes, dCodes2] = newCodes()atau (3) objek ({dCodes, dCodes2} = newCodes())(tidak perlu menggunakan deklarasi di sana @Taylor , meskipun varakan lebih cocok untuk contoh Sasha saat ini).
cregox
241

Anda dapat melakukan ini dari Javascript 1.7 dan seterusnya menggunakan "tugas penataan" . Perhatikan bahwa ini tidak tersedia dalam versi Javascript yang lebih lama (artinya - baik dengan ECMAScript edisi 3 atau 5).

Ini memungkinkan Anda untuk menetapkan 1+ variabel secara bersamaan:

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

// or

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

Anda juga dapat menggunakan perusakan objek yang dikombinasikan dengan singkatan nilai properti untuk memberi nama nilai kembali dalam suatu objek dan memilih yang Anda inginkan:

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

Dan omong-omong, jangan tertipu oleh fakta bahwa ECMAScript memungkinkan Anda untuk melakukannya return 1, 2, .... Apa yang sebenarnya terjadi tidak ada apa yang tampak. Ekspresi dalam pernyataan kembali - 1, 2, 3- tidak lain adalah sebuah operator koma diterapkan pada literal numerik ( 1, 2, dan 3) secara berurutan, yang akhirnya mengevaluasi ke nilai ekspresi yang terakhir - 3. Itu sebabnya return 1, 2, 3secara fungsional identik dengan yang lain return 3.

return 1, 2, 3;
// becomes
return 2, 3;
// becomes
return 3;
Kangax
sumber
1
Hal yang aneh dan menarik tentang contoh terakhir: untuk function foo(){return 1,2,3;}melakukan console.log([].push(foo()))print 1.
Meredith
@ AurélienOoms saya sadari kemudian. Terima kasih
Meredith
1
mengapa var [x, y] = [1, 2]; x; // 1 y; // 2 ini tidak bekerja di chrome? menimbulkan kesalahan; ReferenceError: Sisi kiri tidak valid dalam penugasan
Naveen Agarwal
1
Chrome v49 dirilis seminggu yang lalu mendukung "peruntukan penugasan" out-of-the-box.
Eugene Kulabuhov
1
Ini harus menjadi jawaban yang diterima - penghancuran baru adalah cara terbaik untuk melakukan ini.
Jez
68

Cukup kembalikan objek literal

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
sumber
@SeanKinsey Saya suka solusi ini. Semoga bermanfaat bagi saya. Satu pertanyaan, haruskah ada kebutuhan untuk suatu fungsi sebagai imbalannya, akankah setiap instance hasil ( result1 .. resultN ) mendapatkan salinan fungsinya sendiri atau akankah ada penolakan terhadap kode fungsi? (Saya tidak tahu bagaimana saya bisa menguji ini.) TIA.
Karl
44

Sejak ES6 Anda dapat melakukan ini

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

let {dCodes, dCodes2} = newCodes()

Pengembalian ekspresi {dCodes, dCodes2}adalah singkatan nilai properti dan setara dengan ini {dCodes: dCodes, dCodes2: dCodes2}.

Penugasan ini pada baris terakhir disebut penugasan penghancuran objek . Ini mengekstraksi nilai properti objek dan menugaskannya ke variabel dengan nama yang sama. Jika Anda ingin menetapkan nilai kembali ke variabel nama yang berbeda, Anda bisa melakukannya seperti inilet {dCodes: x, dCodes2: y} = newCodes()

Peracek
sumber
27

Ecmascript 6 termasuk "tugas penataan" (seperti yang disebutkan kangax) sehingga di semua browser (tidak hanya Firefox) Anda akan dapat menangkap array nilai tanpa harus membuat array bernama atau objek untuk tujuan menangkapnya saja.

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

Anda dapat mencobanya di Firefox!

pengguna3015682
sumber
24

Layak lain untuk menyebutkan sintaks yang baru diperkenalkan (ES6) adalah penggunaan singkatan pembuatan objek selain untuk menghancurkan tugas.

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

Sintaks ini dapat di-polyfill dengan babel atau polyfiller js lainnya untuk browser lama tetapi untungnya sekarang berfungsi secara native dengan versi terbaru Chrome dan Firefox.

Tetapi ketika membuat objek baru, alokasi memori (dan akhirnya beban gc) terlibat di sini, jangan berharap banyak kinerja darinya. JavaScript bukanlah bahasa terbaik untuk mengembangkan hal-hal yang sangat optimal, tetapi jika itu diperlukan, Anda dapat mempertimbangkan untuk menempatkan hasil Anda pada objek di sekitarnya atau teknik semacam itu yang biasanya merupakan trik kinerja umum antara JavaScript, Jawa dan bahasa lainnya.

Ebrahim Byagowi
sumber
Itu belum bekerja pada IE atau Edge, hanya ingin diperhatikan.
user1133275
Telah menggunakan ini sedikit ... lebih cepat / halus untuk menggunakan array dan menghindari membangun objek jika mungkin seperti yang ditunjukkan oleh @ user3015682.
dkloke
18

Cara terbaik untuk ini adalah

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

Kemudian gunakan

a().f

kembali 4

di ES6 Anda dapat menggunakan kode ini

function a(){
      var d=2;
      var c=3;
      var f=4;
      return {d,c,f}
}
Behnam Mohammadi
sumber
Kemudian jalankan kembali fungsi untuk setiap variabel? Itu bukan pendekatan terbaik.
Elia Iliashenko
fungsi ini mengembalikan multi nilai, mungkin bukan pendekatan terbaik.
Behnam Mohammadi
Setiap kali penerjemah bertemu a () ia menjalankan fungsinya lagi. Jadi, var f = a (). F; var c = a (). c; var d = a (). d; akan meluncurkan () tiga kali, yang rawan kehilangan kinerja. Pendekatan yang lebih baik adalah var result = a (); var f = result.f; dll
Elia Iliashenko
1
ok untuk kinerja yang lebih baik, Anda dapat menyimpan nilai ke variabel dan menggunakannya, misalnya var result = a (); dan gunakan nilai result.d atau result.c dan result.f, jadi hanya sekali jalankan fungsi ().
Behnam Mohammadi
9

Selain mengembalikan array atau objek seperti yang direkomendasikan orang lain, Anda juga dapat menggunakan fungsi kolektor (mirip dengan yang ditemukan di The Little Schemer ):

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

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

Saya membuat tes jsperf untuk melihat mana dari tiga metode yang lebih cepat. Array tercepat dan kolektor paling lambat.

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

Zelenova
sumber
Biasanya collectordisebut continuationdan teknik ini disebut CPS
ceving
7

Di JS, kita dapat dengan mudah mengembalikan tuple dengan array atau objek, tapi jangan lupa! => JS adalah callbackbahasa yang berorientasi, dan ada sedikit rahasia di sini untuk "mengembalikan beberapa nilai" yang belum ada yang disebutkan, coba ini:

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

menjadi

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

:)

bam! Ini hanyalah cara lain untuk menyelesaikan masalah Anda.

Alexander Mills
sumber
6

Menambahkan bagian-bagian penting yang hilang untuk menjadikan pertanyaan ini sumber daya yang lengkap, karena ini muncul dalam hasil pencarian.

Destrukturisasi Objek

Dalam perusakan objek, Anda tidak perlu menggunakan nilai kunci yang sama dengan nama variabel Anda, Anda dapat menetapkan nama variabel yang berbeda dengan mendefinisikannya seperti di bawah ini:

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

Destrukturisasi Array

Dalam perusakan array, Anda dapat melewati nilai yang tidak Anda butuhkan.

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

Perlu diperhatikan bahwa ...restharus selalu ada di akhir karena tidak masuk akal untuk menghancurkan apa pun setelah semua yang lain digabungkan rest.

Saya harap ini akan menambah nilai pada pertanyaan ini :)

Nimeshka Srimal
sumber
5

Anda juga dapat melakukan:

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

Cara yang sangat umum untuk mengembalikan beberapa nilai dalam javascript adalah menggunakan literal objek , jadi sesuatu seperti:

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

dan dapatkan nilai-nilai seperti ini:

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

atau bahkan cara yang lebih pendek:

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

dan dapatkan secara individual seperti:

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

Anda dapat menggunakan "Object"

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

    return obj;
}
sebu
sumber
1
Ini cara untuk menggunakan IE. Kemudian gunakan seperti: let obj = newCodes (); alert (obj.dCodes);
Asen Kasimov
3

Semuanya benar. returnsecara logis memproses dari kiri ke kanan dan mengembalikan nilai terakhir.

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

>> foo()
>> 3
Artemii
sumber
1
yang ,merupakan operator dan dapat digunakan dalam ekspresi apapun. Tidak ada yang istimewa di returnsini.
gman
3

Saya akan menyarankan untuk menggunakan penugasan perusakan terbaru (Tapi pastikan itu didukung di lingkungan Anda )

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

Saya tahu dua cara untuk melakukan ini: 1. Kembali sebagai Array 2. Kembali sebagai Objek

Inilah contoh yang saya temukan:

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

Beberapa hari yang lalu saya memiliki persyaratan yang sama untuk mendapatkan beberapa nilai pengembalian dari fungsi yang saya buat.

Dari banyak nilai kembali, saya memerlukannya untuk mengembalikan hanya nilai spesifik untuk kondisi tertentu dan kemudian nilai pengembalian lainnya sesuai dengan kondisi lainnya.


Berikut adalah contoh bagaimana saya melakukan itu:

Fungsi:

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

Mendapatkan nilai balik yang diperlukan dari objek yang dikembalikan oleh fungsi:

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

Inti dari menjawab pertanyaan ini adalah untuk membagikan pendekatan ini dalam mendapatkan Tanggal dalam format yang baik. Semoga ini bisa membantu Anda :)

krupesh Anadkat
sumber
1

Saya tidak menambahkan baru di sini tetapi cara alternatif lain.

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

Yah kita tidak bisa melakukan apa yang Anda coba. Tetapi sesuatu yang mungkin di bawah ini dapat dilakukan.

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

Lalu saat memanggil metode

const {x,y} = multiReturnValues();

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