在JavaScript中调用和传递嵌套函数

在JavaScript中调用和传递嵌套函数,javascript,function,callback,nested-function,Javascript,Function,Callback,Nested Function,我有一个函数,返回一系列数字的LCM。它工作得很好,但它有一个函数内部的函数内部的函数。我的问题是,为什么不能通过从嵌套的smallestCommon()中删除scm()来简化它?为什么这个特定的解决方案需要如此深入嵌套的if-else功能 function smallestCommons(arr) { var max = Math.max(...arr); var min = Math.min(...arr); var candidate = max; var smalles

我有一个函数,返回一系列数字的LCM。它工作得很好,但它有一个函数内部的函数内部的函数。我的问题是,为什么不能通过从嵌套的smallestCommon()中删除scm()来简化它?为什么这个特定的解决方案需要如此深入嵌套的if-else功能

function smallestCommons(arr) {
  var max = Math.max(...arr);
  var min = Math.min(...arr);
  var candidate = max;

  var smallestCommon = function(low, high) {
  // inner function to use 'high' variable
    function scm(l, h) {
      if (h % l === 0) {
         return h;
      } else {
        return scm(l, h + high);
      }
    }
    return scm(low, high);
  };

  for (var i = min; i <= max; i += 1) {
    candidate = smallestCommon(i, candidate);
  }

  return candidate;
}

smallestCommons([5, 1]); // should return 60
smallestCommons([1, 13]); // should return 360360
smallestCommons([23, 18]); //should return 6056820
function smallestCommons(arr){
var max=数学最大值(…arr);
var min=数学最小值(…arr);
var候选者=最大值;
var smallestCommon=功能(低、高){
//使用“高”变量的内部函数
函数scm(l,h){
如果(h%l==0){
返回h;
}否则{
返回scm(l、h+高);
}
}
返回scm(低、高);
};

对于(var i=min;i,如果以这样的方式重写内部函数,使其不引用外部范围内的变量,则可以取消对它的测试

function scm(l, h, step) {
  if (h % l === 0) {
     return h;
  } else {
    return scm(l, h + h, step);
  }
}

function smallestCommons(arr) {
  var max = Math.max(...arr);
  var min = Math.min(...arr);
  return scm(min, max, max);
}

这可能会破坏堆栈,但这是另一个问题。如果出现
范围错误
,则必须将
scm
重写为基于循环的,而不是递归的。

如果以这样的方式重写内部函数,使其不引用外部范围内的变量,则可以取消对其的调用

function scm(l, h, step) {
  if (h % l === 0) {
     return h;
  } else {
    return scm(l, h + h, step);
  }
}

function smallestCommons(arr) {
  var max = Math.max(...arr);
  var min = Math.min(...arr);
  return scm(min, max, max);
}

这可能会破坏你的堆栈,但这是另一个问题。如果你遇到
范围错误
,你必须重写
scm
,使其基于循环而不是递归。

拥有内部函数并不一定是坏事。有时你想减少一些本地重复,但又不想创建新的顶级函数。使用c谨慎地说,他们可以清理代码

但是,在您的特定情况下,不需要嵌套它。您只需将
high
变量作为第三个参数传入即可:

function scm(l, h, high) {
  if (h % l === 0) {
     return h;
  } else {
    return scm(l, h + high, high);
  }
}

function smallestCommon (low, high) {
  return scm(low, high, high);
}
在处理递归时,这实际上是一种相当常见的模式:有一个递归函数和一个简化调用递归函数的助手函数。但是在递归很常见的函数式语言中


令人遗憾的是,
smallestCommons
基本上只是在
[min,max]
范围上的一个缩减。在缺少
范围
函数和
smallestCommon
参数顺序错误之间,将代码转换为使用
reduce
不幸有点笨重:

function smallestCommons(arr) {
  var max = Math.max(...arr);
  var min = Math.min(...arr);

  return Array.from(new Array(max - min), (x,i) => i + min)
              .reduce((acc, i) => smallestCommon(i, acc), max);
}

拥有内部函数并不一定是坏事。有时你想减少一些本地重复,但又不想创建一个新的顶级函数。仔细使用,它们可以清理代码

但是,在您的特定情况下,不需要嵌套它。您只需将
high
变量作为第三个参数传入即可:

function scm(l, h, high) {
  if (h % l === 0) {
     return h;
  } else {
    return scm(l, h + high, high);
  }
}

function smallestCommon (low, high) {
  return scm(low, high, high);
}
在处理递归时,这实际上是一种相当常见的模式:有一个递归函数和一个简化调用递归函数的助手函数。但是在递归很常见的函数式语言中


令人遗憾的是,
smallestCommons
基本上只是在
[min,max]
范围上的一个缩减。在缺少
范围
函数和
smallestCommon
参数顺序错误之间,将代码转换为使用
reduce
不幸有点笨重:

function smallestCommons(arr) {
  var max = Math.max(...arr);
  var min = Math.min(...arr);

  return Array.from(new Array(max - min), (x,i) => i + min)
              .reduce((acc, i) => smallestCommon(i, acc), max);
}

我建议将其分解为更小的部分。您将拥有许多易于编写和调试的函数,而不是一个复杂且难以调试的函数。更小的函数也更易于在程序的其他部分进行测试和重用-

const gcd=(m,n)=>
n==0
M
:gcd(n,m%n)
常数lcm=(m,n)=>
数学abs(m*n)/gcd(m,n)
console.log
(lcm(1,5)//5
,lcm(3,4)//12
,lcm(23,18)//414

)
我建议将其分解为更小的部分。您将拥有许多易于编写和调试的函数,而不是一个复杂且难以调试的函数。更小的函数也更容易在程序的其他部分进行测试和重用-

const gcd=(m,n)=>
n==0
M
:gcd(n,m%n)
常数lcm=(m,n)=>
数学abs(m*n)/gcd(m,n)
console.log
(lcm(1,5)//5
,lcm(3,4)//12
,lcm(23,18)//414

)
LCM=最低公倍数吗?如果是,则不清楚
[5,1]
的LCM为什么是
60
(LCM=最低公倍数)5和1的LCM是5。1和13的LCM是13。23和18的LCM是414。我对你要找的东西有点困惑。没有必要嵌套这些函数的声明。如果你提取
scm
函数并在
smallestCommons
内部调用它,
smallestCommon
函数,它们会运行得更快on是完全无关的,因为它所做的只是定义
scm
并返回调用
scm
。LCM是否为最低公倍数?如果是,则不清楚
[5,1]
的LCM为什么为
60
(LCM=最低公倍数)5和1的LCM是5。1和13的LCM是13。23和18的LCM是414。我对你要找的东西有点困惑。没有必要嵌套这些函数的声明。如果你提取
scm
函数并在
smallestCommons
内部调用它,
smallestCommon
函数,它们会运行得更快考虑到它所做的一切是定义
scm
并返回调用
scm
,on完全是无关的。很好的解释,我完全同意您对该用例的评估。回答很好。我们处理问题的方式类似:DGreat解释,我完全同意您对该用例的评估。回答很好。我们类似地处理这个问题:D