javascript - 使用 'return' 在函数中创建函数好吗?

标签 javascript function

当我研究函数时,我意识到我可以创建嵌入式函数。首先,我认为它可能对构建代码有用。但现在我认为这不是好的编码风格。我对吗?这是一个例子。

function show () {
    return function a() {
        alert('a');
        return function b() {
            alert('b');
        }
    }
}

我可以使用这个字符串调用 alert('b'):show()();

在什么情况下使用这种方法比较好,在什么情况下不适合?

最佳答案

是的,这有很多用途。

柯里化(Currying)

首先,您可能想使用 currying ,您可以在其中封装具有单个参数的函数和具有多个参数的函数。例如,

function getHandler(num){
 return function(){
  alert(num);
 }
}

myElement.onclick=getHandler(1)
myOtherElement.onclick=getHandler(25)
anotherElement.onclick=getHandler(42)

onclick() 在被系统调用时不能被赋予任意参数。这不是编写 3 个不同的处理程序来提醒不同的数字,而是通过创建一个可以生成“提醒数字”类型的任意处理程序的函数来减少膨胀。当然,这是一个相当简单的例子,但如果必须做比 alert() 复杂得多的事情,柯里化(Currying)的好处是显而易见的。

效率

另一种情况是,当您有一个复杂的函数时,它有一个计算量大的部分,后面是计算量小的部分。这两部分采用不同的参数,通常第一部分的参数是相同的。 memoization 的一些变体可以用来解决这个问题,但是函数作为返回值也可以。

例如,假设您有以下形式的函数:

function doSomething(a,b,c,x,y){
//Do some complicated calculations using a,b,c, the results go to variables e,f,g

//Do some simple calculations using e,f,g,x,y, return result
}

如果我想运行 doSomething(1,2,3,18,34)+doSomething(1,2,3,55,35)+doSomething(1,2,3,19,12),每次都执行 long 部分,需要 3 倍的执行时间。

不过,我们可以这样写:

function doSomethingCreator(a,b,c){
//Do some complicated calculations using a,b,c, the results go to variables e,f,g
 return function(x,y){
  //Do some simple calculations using e,f,g,x,y, return result
 }
}

现在,我需要做的就是为我的参数集调用 doSomethingCreator(),并使用创建的函数(速度很快)来获得最终结果。代码变为:

var doSomething123=doSomethingCreator(1,2,3);
console.log(doSomething123(18,34)+doSomething123(55,35)+doSomething123(19,12))

这方面的一个例子是求解微分方程。如果给定了一些“边界条件”,微分方程就没有单一的解决方案。然而,(尤其是对于齐次方程),在一个点之后很容易改变边界条件并得到解。通常需要针对不同的边界条件多次求解相同方程。所以,如果你想写一个库方法,你可以让它以齐次方程作为输入,它会返回一个函数,反过来可以给边界条件作为输入来得到最终的解决方案。

通过闭包的“静态”变量

有时,您希望能够轻松创建一组变量并将它们随身携带。

例如,如果你想创建一个计数器函数:

function generateCounter(){
var c=0;
return function(){
        c++; 
        return c;
       }
}

我们可以用它来做很多独立的计数器,例如:

myCtr1=generateCounter();
myCtr2=generateCounter();

myCtr1(); //Returns 1
myCtr1(); //Returns 2
myCtr2(); //Returns 1
myCtr1(); //Returns 3
myCtr2(); //Returns 2

每个计数器都是独立的。当然,在这种情况下,直接使用 myCtr1=0;myCtr2=0 然后使用 ++ 运算符会更容易,但是如果你想记录他们增加的时间?扩展 ++ 案例会涉及很多代码重复,但是,在这里我们可以很容易地调整它:

function generateCounter(){
var c=[]; // The length of c is the value of the counter
return function(){
        c.push((new Date()).getTime()); 
        return c;
       }
}

什么时候不应该使用它

只要这样做没有明显的好处。

除了当你想将它用于闭包绑定(bind)变量时,对于外部函数使用 0 个参数通常没有多大意义,因为内部函数成为相同的函数。看看它是否真的改进了程序,然后使用它。

关于javascript - 使用 'return' 在函数中创建函数好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20176778/

相关文章:

javascript - 删除事件监听器不起作用

php - 构建要在 while 循环中外部使用的字符串

javascript - 如何删除满足特定条件时先前调用的函数?

javascript - AngularJS JavaScript 语法错误

javascript - 尝试从函数返回有效的电子邮件

javascript - 用 `for` 循环替换 `forEach` 循环

javascript - 如何理解 Javascript Redux 中间件中的这种语法

javascript - JS 在函数运行时使用字符串调用函数

Javascript - 更新对象属性的函数

jquery - jQuery Accordion 中的可见性