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