2010-05-26 3 views
508

Я пытаюсь вернуть два значения в JavaScript. Это возможно?Вернуть несколько значений в JavaScript?

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

вы можете решить это, используя обратные вызовы, если вы этого захотите, см. Мой ответ. Люди забывают, что вы можете легко «возвращать несколько значений» с помощью JS, используя кортежи или даже: обратные вызовы! –

+3

Ответы устарели. Теперь это возможно. http://2ality.com/2014/06/es6-multiple-return-values.html –

ответ

830

Нет, но вы можете вернуть массив, содержащий ваши значения:

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

Тогда вы можете получить доступ к ним так:

var codes = newCodes(); 
var dCodes = codes[0]; 
var dCodes2 = codes[1]; 

Если вы хотите поставить «метки» на каждое из возвращаемых значений (проще в обслуживании), вы можете вернуть объект:

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

И доступ к ним:

var codes = newCodes(); 
var dCodes = codes.dCodes; 
var dCodes2 = codes.dCodes2; 
+88

Или вы можете вернуть объект: 'return {dCodes: dCodes, dCodes2: dCodes2};', чтобы упростить ссылку. – Intelekshual

+7

вы можете даже вернуть объект {: dCodes: dCodes, dCodes2: dCodes2} функционально то же самое, но когда вы ссылаетесь на свой возвращенный объект, у вас есть более читаемый код как obj.dCodes и obj.dCodes2 vs obj [0] и obj [1] –

+1

@alexela Конечно, вы можете просто использовать var dCodes = newCodes(). dCodes; var dCodes2 = newCodes(). DCodes2 Однако вы вызовите функцию дважды, что может быть пустой тратой ресурсов, если она сложна. –

49

Просто возвращает объект буквального

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

Нет ли синтаксической ошибки в вашем возвращении? Разве вам не хватает другой двоеточия, как в «dCodes2: dCodes2»? – Volomike

+0

Действительно есть (был) :) –

+0

@SeanKinsey Мне это нравится. Это может быть полезно для меня. Один вопрос, должна ли быть необходимость в функции в возврате, будет ли каждый экземпляр _result_ (_result1_ .. _resultN_) получить свою собственную копию функции или будет ли существовать код функции? (Я не знаю, как я мог проверить это.) TIA. – Karl

127

Вы можете сделать это с JavaScript 1.7 и далее, используя "destructuring assignments". Обратите внимание, что они недоступны в старых версиях Javascript (что означает - ни с ECMAScript 3rd, ни с 5-ю изданиями).

Это позволяет назначать 1+ переменным одновременно:

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

// or 

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

Вы также можете использовать object destructuring combined with property value shorthand назвать возвращаемые значения в объекте и выбрать те, которые вы хотите:

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

И, кстати, не обманывайтесь тем, что ECMAScript позволяет вам return 1, 2, .... Что действительно происходит, не может показаться. Выражение в возвратном выражении - 1, 2, 3 - это не что иное, как оператор запятой, применяемый к числовым литералам (1, 2 и 3) последовательно, который в итоге оценивает значение его последнего выражения - 3. Вот почему return 1, 2, 3 функционально идентичен не более, чем return 3.

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

Странная и интересная вещь о последнем примере: для функции foo() {return 1,2,3;} 'doing' console.log ([]. Push (foo())) 'prints out 1. – Meredith

+8

@ Мередит это потому, что push возвращает длину массива ... –

+0

@ AurélienOoms Я понял позже. Спасибо – Meredith

21

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 уже!

5

Кроме возвращающий массив или объект, как другие рекомендовали, вы можете также использовать функцию коллектора (по аналогии с найденным в Маленький Schemer):

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

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

Я сделал тест JSPerf чтобы увидеть, какой из трех методов работает быстрее. Массив быстрее, а сборщик - медленнее.

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

13

Лучший способ для этого

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} 
} 
+0

Затем выполните функцию снова для каждой переменной? Это не лучший подход. –

+0

Эта функция возвращает многозначное значение, возможно, это не лучший подход. –

+0

Каждый раз, когда интерпретатор встречает a(), он снова запускает функцию. Итак, var f = a(). F; var c = a(). c; var d = a(). d; запустит() три раза, что будет связано с потерей производительности. Лучшим подходом будет var result = a(); var f = result.f; и т. д. –

3

Вы также можете сделать:

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

const {d,c,f} = a() 
+0

Это просто работа в ES6 –

17

Еще стоит упомянуть, чтобы вновь вводимый (ES6) синтаксис является использование объекта создания стенографии в дополнении к разрушающим назначениям.

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

Этот синтаксис может быть polyfilled с Вавилонской или других JS polyfiller для старых браузеров, но, к счастью, в настоящее время работает изначально с последними версиями Chrome и Firefox.

Но поскольку здесь задействован новый объект, распределение памяти (и возможная загрузка gc), не ожидайте от него большой производительности. JavaScript не лучший язык для разработки очень оптимальных вещей в любом случае, но если это необходимо, вы можете рассмотреть возможность поместить свой результат на окружающий объект или такие методы, которые обычно являются общими трюками производительности между JavaScript, Java и другими языками.

+0

Это еще не работает на IE или Edge, просто хотелось бы отметить. – user1133275

+0

Использовал это совсем немного ... быстрее или плавнее использовать массив и не создавать конструкцию объекта, если это возможно, как показано пользователем @ user3015682. – dkloke

3

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

:)

б/у! Это просто еще один способ решения вашей проблемы.

0

Вы можете использовать "Объект"

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

    return obj; 
} 
1

Все правильно. return логически обрабатывает слева направо и возвращает последнее значение.

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

>> foo() 
>> 3 
+0

',' является оператором и может использоваться в любом выражении. Здесь нет ничего особенного о возврате. – gman

0

С 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()

Смежные вопросы