在JavaScript中返回多个值?

Aut*_*cus 762 javascript

我试图在JavaScript中返回两个值.那可能吗?

var newCodes = function() {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return dCodes, dCodes2;
};
Run Code Online (Sandbox Code Playgroud)

Sas*_*gov 1159

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

function getValues() {
    return [getFirstValue(), getSecondValue()];
}
Run Code Online (Sandbox Code Playgroud)

然后您可以这样访问它们:

var values = getValues();
var first = values[0];
var second = values[1];
Run Code Online (Sandbox Code Playgroud)

如果要在每个返回值上放置"标签"(更易于维护),则可以返回一个对象:

const [first, second] = getValues();
Run Code Online (Sandbox Code Playgroud)

并访问它们:

function getValues() {
    return {
        first: getFirstValue(),
        second: getSecondValue(),
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以返回一个对象:`return {dCodes:dCodes,dCodes2:dCodes2};`以便于引用. (142认同)
  • @VadimKirilchuk无需使用[解构分配](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)调用两次 - 例如.`const {dCodes,dCodes2} = newCodes();` (11认同)
  • 你甚至可以返回一个对象{:dCodes:dCodes,dCodes2:dCodes2}在功能上相同,但是当你引用你的返回对象时,你有更多可读代码作为obj.dCodes和obj.dCodes2 vs obj [0]和obj [1 ] (10认同)
  • 正如其他答案所说(以及暗示的评论),ES6在这里提供了一些选择.3是精确的:(1)[对象属性速记](http://es6-features.org/#PropertyShorthand)`返回{dCodes,dCodes2}`工作只是一样@Intelekshual提到和(2)使用相同的函数你可以简单地用解构数组来访问它们`[dCodes,dCodes2] = newCodes()`或(3)对象`({dCodes,dCodes2} = newCodes())`(不需要在@Taylor使用声明,虽然`var`会更适合当前Sasha的例子). (6认同)
  • @alexela当然你可以简单地使用 var dCodes = newCodes().dCodes; var dCodes2 = newCodes().dCodes2 但是,您将调用该函数两次,如果函数很复杂,则可能会浪费资源。 (2认同)

kan*_*gax 225

您可以使用"解构分配"从Javascript 1.7开始执行此操作.请注意,这些版本在较旧的Javascript版本中不可用(意思是 - 无论是ECMAScript 3rd还是5th edition).

它允许您同时分配1+个变量:

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

// or

[x, y] = (function(){ return [3, 4]; })();
x; // 3
y; // 4
Run Code Online (Sandbox Code Playgroud)

您还可以使用对象解构与属性值缩写相结合来命名对象中的返回值并选择所需的值:

let {baz, foo} = (function(){ return {foo: 3, bar: 500, baz: 40} })();
baz; // 40
foo; // 3
Run Code Online (Sandbox Code Playgroud)

顺便说一句,不要被ECMAScript允许的事实所迷惑return 1, 2, ....真正发生的事情并非如此.在return语句表达- 1, 2, 3-不过是应用于数字文字一个逗号(1,23)顺序,最终计算结果为它的最后一个表达式的值- 3.这就是为什么return 1, 2, 3功能上只相同而已return 3.

return 1, 2, 3;
// becomes
return 2, 3;
// becomes
return 3;
Run Code Online (Sandbox Code Playgroud)

  • 关于最后一个例子的奇怪而有趣的事情:对于 `function foo(){return 1,2,3;}` 做 `console.log([].push(foo()))` 打印出 1。 (2认同)

Sea*_*sey 62

只需返回一个对象文字

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);
Run Code Online (Sandbox Code Playgroud)


Per*_*cek 36

从ES6开始,你就可以做到这一点

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

let {dCodes, dCodes2} = newCodes()
Run Code Online (Sandbox Code Playgroud)

返回表达式{dCodes, dCodes2}属性值的简写,与此等效{dCodes: dCodes, dCodes2: dCodes2}.

最后一行上的这个赋值称为对象破坏赋值.它提取对象的属性值并将其分配给同名变量.如果您想将返回值分配给不同名称的变量,您可以这样做let {dCodes: x, dCodes2: y} = newCodes()


use*_*682 26

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(); 
Run Code Online (Sandbox Code Playgroud)

你可以在Firefox中试试吧!


Ebr*_*owi 22

另一个值得一提的新引入(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);
Run Code Online (Sandbox Code Playgroud)

这种语法可以与旧版浏览器的babel或其他js polyfiller一起使用,但幸运的是现在可以使用最新版本的Chrome和Firefox.

但是在创建一个新对象时,这里涉及内存分配(以及最终的gc加载),不要指望它有太多的性能.JavaScript不是开发高度优化的东西的最佳语言,但如果需要,你可以考虑将结果放在周围的对象或这些技术上,这些技巧通常是JavaScript,Java和其他语言之间的常见性能技巧.


Beh*_*adi 17

最好的方法是

function a(){
     var d=2;
     var c=3;
     var f=4;
     return {d:d,c:c,f:f}
}
Run Code Online (Sandbox Code Playgroud)

然后用

a().f
Run Code Online (Sandbox Code Playgroud)

返回4

在ES6中,您可以使用此代码

function a(){
      var d=2;
      var c=3;
      var f=4;
      return {d,c,f}
}
Run Code Online (Sandbox Code Playgroud)

  • 然后为每个变量再次运行该函数?这不是最好的方法。 (2认同)

Zel*_*ova 7

除了像其他人推荐的那样返回数组或对象之外,您还可以使用收集器函数(类似于The Little Schemer函数):

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

var x,y;
a(function(a,b){
  x=a;
  y=b;
});
Run Code Online (Sandbox Code Playgroud)

我做了一个jsperf测试,看看这三种方法中哪一种更快.数组最快,收集器速度最慢.

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


Ali*_*eza 7

在 javascript 中返回多个值的一种非常常见的方法是使用对象文字,例如:

const myFunction = () => {
  const firstName = "Alireza", 
        familyName = "Dezfoolian",
        age = 35;
  return { firstName, familyName, age};
}
Run Code Online (Sandbox Code Playgroud)

并获得如下值:

myFunction().firstName; //Alireza
myFunction().familyName; //Dezfoolian
myFunction().age; //age
Run Code Online (Sandbox Code Playgroud)

甚至更短的方式:

const {firstName, familyName, age} = myFunction();
Run Code Online (Sandbox Code Playgroud)

并单独获取它们,例如:

firstName; //Alireza
familyName; //Dezfoolian
age; //35
Run Code Online (Sandbox Code Playgroud)


Jor*_*ans 6

你也可以这样做:

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

const {d,c,f} = a()
Run Code Online (Sandbox Code Playgroud)


Ale*_*lls 6

在JS中,我们可以轻松返回带有数组或对象的元组,但不要忘记!=> JS是一种callback定向语言,这里有一个小秘密用于"返回多个值",没有人提到过,试试这个:

var newCodes = function() {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    return dCodes, dCodes2;
};
Run Code Online (Sandbox Code Playgroud)

var newCodes = function(fg, cb) {  
    var dCodes = fg.codecsCodes.rs;
    var dCodes2 = fg.codecsCodes2.rs;
    cb(null, dCodes, dCodes2);
};
Run Code Online (Sandbox Code Playgroud)

:)

嘭!这只是解决问题的另一种方法.


Nim*_*mal 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);
Run Code Online (Sandbox Code Playgroud)

数组解构

在数组解构中,您可以跳过不需要的值。

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
Run Code Online (Sandbox Code Playgroud)

值得注意的是,...rest应该始终在最后,因为在其他所有内容聚合到rest.

我希望这会给这个问题增加一些价值:)