【问题标题】:Return multiple values in JavaScript?在 JavaScript 中返回多个值?
【发布时间】:2021-07-05 21:39:32
【问题描述】:

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

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

【问题讨论】:

  • 你可以通过回调来解决这个问题,如果你愿意,请看我的回答。人们忘记了你可以使用 JS 轻松地“返回多个值”,使用元组甚至:回调!
  • 答案已经过时了。现在是可能的。 2ality.com/2014/06/es6-multiple-return-values.html
  • 从技术上讲,您仍然返回单个对象/数组,这只是 ES6 中更简单的解构。
  • 我相信 Andrea 指的是“解构”。但是,是的,您仍然不会从函数中返回超过一项:一项可以是包含任意数量的键的对象或具有 n 项的数组。

标签: javascript return multiple-variable-return


【解决方案1】:

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

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

然后你可以像这样访问它们:

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

使用最新的ECMAScript 6 syntax*,还可以更直观地解构返回值:

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

* 浏览器兼容性见this table。基本上,除了 IE 之外的所有现代浏览器都支持这种语法,但是您可以在构建时使用 Babel 之类的工具将 ES6 代码编译为与 IE 兼容的 JavaScript。

【讨论】:

  • 或者您可以返回一个对象:return {dCodes : dCodes, dCodes2 : dCodes2};,以便于引用。
  • 您甚至可以返回一个对象 {:dCodes: dCodes, dCodes2: dCodes2} 功能相同,但是当您引用返回的对象时,您有一些更具可读性的代码,例如 obj.dCodes 和 obj.dCodes2 vs obj[0] 和 obj[1]
  • @alexela 当然你可以简单地使用 var dCodes = newCodes().dCodes; var dCodes2 = newCodes().dCodes2 但是,您将调用该函数两次,如果它很复杂,可能会浪费资源。
  • @VadimKirilchuk 无需使用destructuring assignment 调用它两次——例如。 const { dCodes, dCodes2 } = newCodes();
  • 正如其他答案所说(以及 cmets 暗示),ES6 在这里带来了一些选择。 3 确切地说:(1)object property shorthandreturn {dCodes, dCodes2} 的工作方式与提到的@Intelekshual 相同,并且(2)使用相同的功能,您可以简单地使用解构数组[dCodes, dCodes2] = newCodes() 或(3)对象({dCodes, dCodes2} = newCodes())(无需在 @Taylor 那里使用声明,尽管 var 更适合当前 Sasha 的示例)。
【解决方案2】:

只返回一个对象字面量

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 我喜欢这个解决方案。它可能对我有用。一个问题,如果需要返回函数,result (result1 .. resultN) 的每个实例都会获得自己的副本功能或是否会重复使用功能代码? (我不知道如何对此进行测试。)TIA。
【解决方案3】:

从 ECMAScript 6 开始,您可以使用数组和 "destructuring assignments" 执行此操作。请注意,这些在较旧的 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

您也可以使用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, ... 的事实所迷惑。那里真正发生的事情并不像看起来那样。 return 语句中的表达式 — 1, 2, 3 — 只不过是按顺序应用于数字文字(123)的逗号运算符,最终计算为其最后一个表达式的值 — 3 .这就是为什么return 1, 2, 3 在功能上与return 3 完全相同。

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

【讨论】:

  • 关于最后一个示例的奇怪而有趣的事情:对于 function foo(){return 1,2,3;} 执行 console.log([].push(foo())) 打印出 1。
  • 为什么 var [x, y] = [1, 2]; X; // 1年; // 2 这在 chrome 中不起作用?引发错误; ReferenceError:分配中的左侧无效
  • @NaveenAgarwal Chrome 尚不完全支持指定破坏赋值的 ECMAScript 6
  • Chrome v49 于一周前发布,支持开箱即用的“解构分配”。
【解决方案4】:

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

    除了按照其他人的建议返回数组或对象外,您还可以使用收集器函数(类似于 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
    【解决方案6】:
    function a(){
      var d = 2;
      var c = 3;
      var f = 4;
      return {d: d, c: c, f: f};
    }
    

    然后使用

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

    在新版本中:

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

    【讨论】:

    • 然后为每个变量再次运行函数?这不是最好的方法。
    • 解释器每次遇到 a() 时都会再次运行该函数。所以,var f = a().f; var c = a().c; var d = a().d;会启动 a() 3 次,容易造成性能损失。更好的方法是 var result = a();变量 f = 结果.f;等
    • 为了获得更好的性能,您可以保留变量的值并使用它,例如 var result=a();并使用值 result.d 或 result.c 和 result.f ,因此只需一次运行 a() 函数。
    【解决方案7】:

    你也可以这样做:

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

    【讨论】:

      【解决方案8】:

      另一个值得一提的新引入的 (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 上运行,只是想说明一下。
      • 已经使用了很多...使用数组更快/更顺畅,如果可能的话避免构造对象,如@user3015682所示。
      【解决方案9】:

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

      :)

      砰!这只是解决问题的另一种方式。

      【讨论】:

        【解决方案10】:

        你可以使用“对象”

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

        【讨论】:

        • 这是 IE 的方式。稍后使用如:let obj = newCodes();警报(obj.dCodes);
        【解决方案11】:

        一切都正确。 return 从左到右进行逻辑处理并返回最后一个值。

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

        【讨论】:

        • , 是一个运算符,可以在任何表达式中使用。 return 这里没有什么特别之处。
        【解决方案12】:

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

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

        【讨论】:

          【解决方案13】:

          几天前,我有类似的要求,即从我创建的函数中获取多个返回值。

          从许多返回值中,我需要它只返回给定条件的特定值,然后返回对应于其他条件的其他返回值。


          这是我如何做到的示例:

          功能:

          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;
          

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

          【讨论】:

            【解决方案14】:

            我建议使用最新的解构赋值(但make sure it's supported in your environment

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

            【讨论】:

              【解决方案15】:

              我在这里没有添加任何新东西,而是另一种方式。

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

              【讨论】:

                【解决方案16】:

                我知道有两种方法可以做到这一点: 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>
                

                【讨论】:

                  【解决方案17】:

                  添加缺少的重要部分以使此问题成为完整的资源,因为这会出现在搜索结果中。

                  对象解构

                  在对象解构中,您不一定需要使用与变量名称相同的键值,您可以通过如下定义来分配不同的变量名称:

                  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 之后破坏任何内容没有任何意义。

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

                  【讨论】:

                    【解决方案18】:

                    好吧,我们不能完全按照您的尝试去做。但是可以做以下可能的事情。

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

                    然后在调用方法时

                    const {x,y} = multiReturnValues();
                    
                    console.log(x) ---> 10
                    console.log(y) ---> 20
                    

                    【讨论】:

                      【解决方案19】:

                      在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
                      

                      【讨论】:

                        【解决方案20】:

                        可以使用模板文字`${}`返回一个包含许多值和变量的字符串

                        喜欢:

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

                        简短而简单。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-06-28
                          • 2015-03-27
                          相关资源
                          最近更新 更多