在JavaScript中返回多个值?


844

我试图在JavaScript中返回两个值。这可能吗?

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

您可以通过使用回调来解决此问题,如果您愿意的话,请参阅我的回答。人们忘记了,您可以使用JS,使用元组甚至是回调来轻松“返回多个值”!
亚历山大·米尔斯

16
答案已经过时了。现在有可能。2ality.com/2014/06/es6-multiple-return-values.html
Segal-Halevi

3
从技术上讲,您仍然返回单个对象/数组,这只是在ES6中更简单的解构方法。
Andrea Bergonzo

Answers:


1294

不,但是您可以返回一个包含您的值的数组:

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

10
您甚至可能返回一个对象{:dCodes:dCodes,dCodes2:dCodes2}在功能上是相同的,但是当您引用返回的对象时,您的可读性更高,如obj.dCodes和obj.dCodes2与obj [0]和obj [1 ]
Jonathan S.

1
@alexela确保您可以简单地使用var dCodes = newCodes()。dCodes;。var dCodes2 = newCodes()。dCodes2但是,您将调用该函数两次,如果函数很复杂,可能会浪费资源。
Vadim Kirilchuk '16

12
@VadimKirilchuk无需通过销毁任务来调用它两次-例如。const { dCodes, dCodes2 } = newCodes();
泰勒·埃德米斯顿

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 3rd和5th版本均不提供)。

它允许您同时分配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-不过是一个逗号操作符适用于数字文本(12,和3)顺序,最终计算结果为它的最后一个表达式的值- 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。谢谢
Meredith

1
为什么var [x,y] = [1,2]; X; // 1 y; // 2这在chrome中不起作用?提出错误; ReferenceError:作业中的左侧无效
Naveen Agarwal 2014年

1
Chrome v49于一周前发布,支持即​​用型的“销毁任务”。
尤金·库拉布霍夫

1
这应该是公认的答案-新的结构调整是完成此操作的好方法。
耶兹(Jez),2017年

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我喜欢这个解决方案。这对我可能有用。一个问题,返回中是否需要一个函数,结果的每个实例(result1 .. resultN)都将获得其自己的函数副本,还是会重用该函数代码?(我不知道该如何测试。)TIA。
卡尔

43

从ES6开始,您可以执行此操作

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

let {dCodes, dCodes2} = newCodes()

返回表达式{dCodes, dCodes2}属性值的简写,并且等效于this {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)语法除了破坏分配外,还使用了对象创建速记。

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 polyfiller来填充此语法,但是幸运的是,现在可以在最新版本的Chrome和Firefox中本地运行。

但是当创建一个新对象时,这里会涉及到内存分配(以及最终的gc负载),因此不要期望它会有太多性能。无论如何,JavaScript都不是用于开发高度优化的事物的最佳语言,但是如果需要,您可以考虑将结果放在周围的对象或此类技术上,这通常是JavaScript,Java和其他语言之间的常见性能技巧。


只是要注意,这在IE或Edge上尚不可用。
user1133275

经常使用它...使用数组更快/更顺畅,并且尽可能避免构造一个对象,如@ user3015682所示。
dkloke

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

然后为每个变量再次运行该函数?那不是最好的方法。
伊利亚·伊利亚申科

此函数返回多值,也许不是最佳方法。
Behnam Mohammadi

每次解释器遇到a()时,它将再次运行该函数。因此,var f = a()。f; var c = a()。c; var d = a()。d; 将启动a()3次,这很容易导致性能损失。更好的方法是var result = a(); var f = result.f; 等
埃利亚·伊利亚申科

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测试,以查看三种方法中哪一种更快。阵列最快,而收集器最慢。

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

您也可以这样做:

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

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

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);
阿森·卡西莫夫

3

没错。return从左到右进行逻辑处理并返回最后一个值。

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

>> foo()
>> 3

1
,是操作员,并且可以在任何表达式中。这里没有什么特别的return
gman

3

我建议使用最新的解构分配(但请确保您的环境支持它

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

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;

回答这个问题的重点是分享这种以良好格式获取Date的方法。希望它对您有所帮助:)


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.