Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用函数优于循环有什么好处?_Javascript_Loops_Closures - Fatal编程技术网

Javascript 使用函数优于循环有什么好处?

Javascript 使用函数优于循环有什么好处?,javascript,loops,closures,Javascript,Loops,Closures,函数迭代器似乎正在取代JS中for循环的使用 与for/while循环相比,传递诸如map或reduce之类的函数有什么好处 var numbers = [1, 4, 9]; var doubles = numbers.map(function(num) { return num * 2; }); var doubles = []; for (i = 0; i < numbers.length; i++) { doubles[i] = numbers[i] * 2; }

函数迭代器似乎正在取代JS中for循环的使用

与for/while循环相比,传递诸如
map
reduce
之类的函数有什么好处

var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});

var doubles = [];
for (i = 0; i < numbers.length; i++) { 
    doubles[i] = numbers[i] * 2;
}
var编号=[1,4,9];
var doubles=numbers.map(函数(num){
返回数*2;
});
var Double=[];
对于(i=0;i
这是一个范式转变。后者是命令式编程的一种形式,用户创建计算机使用的数据。前者本质上是一种更基于函数的方法,源于数学,利用已有的数据(代码)

两者在理论(处理)上没有优势,尽管应用于计算机的当前状态,函数式编程随着处理能力的提高变得更加有用


函数式编程允许一种基于数学的推理形式,强调输入和输出。JavaScript尤其擅长处理这种风格,因为函数是一流的数据类型

我不知道为什么您会将
map
的使用称为“闭包”。闭包完全是另一回事
map
是一个高阶函数——定义为对函数进行操作(获取或返回)的函数。这种编程风格可以粗略地称为“函数式”

使用像
map
这样的函数有优点也有缺点。正如一位评论者所指出的,它更加紧凑:

function sum(array) {
  var sum = 0;
  for (var i = 0; i < array.length; i++) sum += array[i];
  return sum;
}
其中
add
函数add(a,b){返回a+b;}

更紧凑意味着可读性更强,bug的表面积更小。名为
add
的函数的使用也提高了可读性;我们可以很容易地直觉地知道,操作是添加数组的元素

基本上,所有数组函数都具有for循环等价物,这需要设置更多变量和编写更多逻辑。例如,
map

function map(array, fn) {
  var result = [];
  for (var i = 0; i < array.length; i++) result.push(fn(array[i]));
  return result;
}
现在我们将每个元素加倍:

function double(array) {
  var result = [];
  for (var i = 0; i < array.length; i++) result.push(array[i] * 2); 
  return result;
}
仅对位于1000000位置的单个元素执行操作,并根据需要返回稀疏数组

功能性风格也为灵活性提供了更多的可能性。假设我们想推广乘法的概念。我可以编写一个高阶函数来创建一个函数,该函数将某个值乘以某个特定因子:

function multiply(n) {
  return function(x) {
    return n * x;
  };
}
现在我可以写作了

array.map(multiply(2))
在for-loop解决方案中很难实现这种简洁性和表达性

forEach
map
等可能比for循环慢。如果您的代码在一个紧循环中运行了一百万次,那么这可能是一个问题。在现实世界中,这很少是一个问题。最好优先考虑代码的可读性和紧凑性

但是,没有人强迫您使用
map
filter
。在ES7或其他任何调用中,您将能够使用数组理解以更可读的方式完成相同的任务:

[ for (i of array) if (i % 2) i + 1 ]
它结合了过滤器和贴图

再远一点,如果您计划编写一个遍历数组的生成器,并从每个元素产生一些计算,那么您需要使用for循环,因为在
forEach
回调中无法产生:

function *double(array) {
  for (var i = 0; i < array.length; i++) yield array[i]*2;
}

function *double(array) {
  array.forEach(elt => yield elt*2); // DOESN'T WORK!!
}
函数*double(数组){
对于(var i=0;iyielt*2);//不起作用!!
}

这里已经有了很好的答案。随着时间的推移,我只想补充一件事:当你用“命令式”/“旧的方式”做事时,它倾向于鼓励一种带有大量中间变量的编程风格,到处都是可变的东西,还有“当我在迭代时,我还可以在相同的数据上做另一件事”这是代码设计中最大的陷阱——牺牲关注点的分离来获得可疑的性能增益。考虑这个例子

const numbers = [1,4,9,16];
let sum = 0;
let onlyEvenNumbers = [];
for(i = 0; i < numbers.length; i++) {
  sum += numbers[i];
  if(numbers[i] % 2 == 0) {
    onlyEvenNumbers.push(numbers[i]);
  }
}

嗯,这不是结束,而是方法的作用
map
reduce
对数组执行特定操作,它们不仅仅像
for
循环那样迭代?简洁性(使用es6中的arrow funcs会更好),如果您不喜欢它们,您不必使用它们,大多数事情都可以在没有新的(ish)的情况下完成数组方法。此处传递给
.map()
的匿名回调形成的闭包基本上与任何代码的工作方式无关。函数本身当然有,但调用形成的闭包却没有……这是一个清晰的声音。几年来我几乎只做js,最近我做了一些php,我受不了回到“旧方式”
[ for (i of array) if (i % 2) i + 1 ]
function *double(array) {
  for (var i = 0; i < array.length; i++) yield array[i]*2;
}

function *double(array) {
  array.forEach(elt => yield elt*2); // DOESN'T WORK!!
}
const numbers = [1,4,9,16];
let sum = 0;
let onlyEvenNumbers = [];
for(i = 0; i < numbers.length; i++) {
  sum += numbers[i];
  if(numbers[i] % 2 == 0) {
    onlyEvenNumbers.push(numbers[i]);
  }
}
const numbers = [1,4,9,16];
const sum = numbers.reduce((acc, val) => acc + val);
const onlyEvenNumbers = numbers.filter(num => num % 2 == 0);