从Javascript函数返回一个值而不使用“return”

时间:2013-12-27 06:59:17

标签: javascript

在JavaScript中,是否有任何机制可以在不使用关键字“return”的情况下设置函数返回值?

4 个答案:

答案 0 :(得分:7)

当然可以。所有其他答案都谈到:

  1. 为父作用域中的变量赋值。
  2. 为父作用域中对象的属性赋值。
  3. 然而,有第三种方法,这种方法非常强大:CONTINUATIONS

    我们假设return是一个函数。例如:

    function add(a, b) {
        return(a + b);
    }
    

    现在如果你不想使用return怎么办?我们可以这样做:

    function add(a, b, ret) {
        ret(a);
    }
    

    简单地说,继续是一个用来代替return语句的函数。更正式地说:

      

    延续是由另一个函数调用的函数。另一个函数做的最后一件事就是调用continuation。之后它没有做任何其他事情。

    因此,延续就像return语句的功能等价物。

    延续有很多好处:

    1. 您可以将多个返回值传递给continuation。
    2. 您可以递归而不是迭代地编写函数。
    3. 您可以选择不调用延续(在这种情况下,您正在更改控制流程)。
    4. 您可以选择调用多个延续中的一个(例如throw延续)。
    5. 然而,延续有两个主要缺点:

      1. 如果你用连续传递方式编写程序,那么你最终会得到许多嵌套函数。
      2. JavaScript没有尾部调用消除。因此,递归函数会增加堆栈大小。
      3. 例如:

        function fib(n, k) {
            switch (n) {
            case 0:  k(0); break;
            case 1:  k(1); break;
            default:
                fib(n - 1, function (x) {
                    fib(n - 2, function (y) {
                        k(x + y);
                    });
                });
            }
        }
        
        fib(20, console.log); // maximum recursion depth exceeded
        

        您可以使用setTimeout来消除尾调用递归:

        Function.prototype.async = function () {
            return setTimeout.bind(null, this, 0).apply(null, arguments);
        };
        
        function fib(n, k) {
            switch (n) {
            case 0:  k(0); break;
            case 1:  k(1); break;
            default:
                fib.async(n - 1, function (x) {
                    fib.async(n - 2, function (y) {
                        k(x + y);
                    });
                });
            }
        }
        
        fib(20, console.log); // 6765
        

        您可以使用backcalls from LiveScript让代码看起来更好:

        Function::async = -> setTimeout.bind(null, @, 0) ...
        
        fib = (n, k) -->
            | n == 0    => k 0
            | n == 1    => k 1
            | otherwise =>
                x <- fib.async n - 1
                y <- fib.async n - 2
                k x + y
        
        fib 20, alert # 6765
        

        您可以在http://livescript.net/网站上亲自试用。只需使用小于20的值即可。最好是10

答案 1 :(得分:2)

没有其他方法可以返回值,这就是return的用途。 但由于我们有副作用,您可以在更广泛的范围内编辑变量,如下所示:

var a = 5;
function setA(x)
{
    a = x;
}
setA(6);

或者,您可以将对象传递给函数,并使用该对象中的引用变量变量。 This页面详细说明了其工作原理。

如上所述, 与结果值相同,因为以下内容将失败:

var newA = setA(a); // undefined instead of 5

答案 2 :(得分:0)

使用一些全局变量 或者如果你想要OOP概念,那么将使用一些类变量并更新而不使用return语句

var num1 = 5;
alert(num1);
function sum(a,b) {
    num1 = a+b; // Function Without return statement
}
//Calling Function
sum(3,4);
alert(num1);

答案 3 :(得分:0)

创建函数的最佳(最具可读性/可测试性)方法是让它们接收所需内容,并返回它们应有的内容。但是,如果由于某种原因需要避免返回,有几种方法可以做到这一点:

在范围

中设置变量

您可以在闭包中创建变量,然后在函数中设置值。

(function() {
  var a = 12;
  var fnc = function() {
    a = 13;
  }
  fnc();
  // value of a is now 13 as a is in scope for fnc
})();

创建全局对象

您可以创建一个全局对象并在其上设置一个属性:

window.app = window.app || {};
app.a = 12;

var b = function() {
  app.a = 13;
}
b();
// the value of app.a is now 13 as app is in scope for fnc