Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
Functional programming 比较javascripts native“;for loop";原型';s每个()_Functional Programming_Loops_Javascript - Fatal编程技术网

Functional programming 比较javascripts native“;for loop";原型';s每个()

Functional programming 比较javascripts native“;for loop";原型';s每个(),functional-programming,loops,javascript,Functional Programming,Loops,Javascript,所以我和一位同事就JavaScript中的循环进行了辩论。问题是关于原生for循环构造和原型的each()方法。现在我知道有很多关于for和for的文档/博客,但这场辩论有些不同,我想听听你们中的一些人的想法 让我们以下面的循环为例 例1 在本例中,我们可以立即看到构造的代码更少,但是,我认为每次循环对象时,我们都必须创建一个新函数来处理所讨论的操作。因此,对于具有大量对象的集合来说,这将非常糟糕。因此,我朋友的观点是,由于其功能性方法,示例2比示例1更容易理解,实际上更干净。我的论点是,任何程

所以我和一位同事就JavaScript中的循环进行了辩论。问题是关于原生for循环构造和原型的each()方法。现在我知道有很多关于for和for的文档/博客,但这场辩论有些不同,我想听听你们中的一些人的想法

让我们以下面的循环为例

例1


在本例中,我们可以立即看到构造的代码更少,但是,我认为每次循环对象时,我们都必须创建一个新函数来处理所讨论的操作。因此,对于具有大量对象的集合来说,这将非常糟糕。因此,我朋友的观点是,由于其功能性方法,示例2示例1更容易理解,实际上更干净。我的论点是,任何程序员都应该能够理解示例1,因为它是在编程101中教授的。因此,更简单的参数不适用,示例1的性能优于示例2。那为什么还要费心于#2。现在,在仔细阅读之后,我发现当数组大小很小时,示例2的开销很小。然而,人们一直在谈论您编写的代码行数较少,而且示例1容易出错。我仍然不相信这些理由,所以我想知道你们怎么想…

答案是——这是主观的


对我来说,示例2实际上并没有那么少的代码,它还涉及到在您可以使用它之前下载(带宽)和解析/执行(执行时间)一个约30kb的库-因此,不仅方法本身的效率较低,而且还涉及到设置开销。对我来说,认为示例2更好是愚蠢的-然而,这只是一种观点,许多人会(并且完全有资格)完全不同意。

在第二个示例中,您没有在每次迭代中创建新函数。只有一个函数不断被调用。为了澄清只使用一个函数的观点,考虑如何实现<代码>每个方法。
Array.prototype.each = function(fn) {
    for(var i = 0; i < this.length; i++) {
        // if "this" should refer to the current object, then
        // use call or apply on the fn object
        fn(this[i]);
    }
}

// prints each value (no new function is being created anywhere)
[1, 2, 3].each(function(v) { console.log(v); });
标记所有5次出现的所有
i
与注释内联。我们本可以轻松地将索引
i
全部删除

people.forEach(function(person) {
    person.updateRecords();
    person.increaseSalary();
});

对我来说,好处不在于减少代码行数,而是从代码中删除不必要的细节。这也是为什么大多数程序员在Java中的迭代器可用时就开始使用迭代器的原因,后来在它出现时又开始使用
enhanced
for循环的原因。同样的理由不适用于JavaScript的论点并不适用。

我相当肯定它不会为每次迭代创建新的代码函数,而是在每次迭代中调用该函数。在内部跟踪迭代器可能需要更多的开销(有些语言允许更改列表,有些不允许),但在内部,它与过程版本不应该有太大的不同


但当你问哪个更快时,你应该问,这真的重要吗?您是否在其上安装了代码分析器并使用真实数据对其进行了测试?你可以花很多时间去弄清楚哪个更快,但如果它只占你执行时间的0.0001%,谁在乎呢?使用分析工具找出真正重要的瓶颈,并使用您和您的团队同意的更易于使用和阅读的迭代方法。

示例一不仅容易出错,对于长度很小的数组来说,这是一个糟糕的选择,而且每个(或forEach,如JavaScript 1.6中定义的,但IE8仍然不支持它)绝对是时尚的更好选择

原因很简单:您是在告诉代码要做什么,而不是如何做。在我对firefox的测试中,forEach方法的速度大约是for循环速度的30%。但是当你在做微型阵列的时候,它甚至没有那么重要。让你的代码更干净、更容易理解(记住:它在做什么,而不是如何做),这不仅是为了你下次再来时的理智,也是为了其他人看你的代码时的理智

如果您包含原型的唯一原因是为了.each方法,那么您就做错了。如果您想要的只是一个干净的迭代方法,请使用.forEach方法——但请记住定义自己的方法。这是forEach上的MDC页面中的内容,这是一个有用的检查,可以为自己提供一个.forEach方法(如果不存在):

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}
if(!Array.prototype.forEach)
{
Array.prototype.forEach=函数(fun/*,thisp*/)
{
var len=this.length>>>0;
如果(乐趣的类型!=“功能”)
抛出新的TypeError();
var thisp=参数[1];
对于(变量i=0;i

从它的工作原理可以看出,虽然为每个项目调用了新函数,但并没有为每个项目创建新函数。

在我看来,第二种方法简洁且易于使用,但如果您想使用
中断
继续
,它会变得复杂(请参见原型文档)。请参阅文档


所以,如果您使用的是简单的迭代,使用each()函数在我看来会更好,因为它可能更简洁、更容易理解,尽管它的性能不如原始for循环

它真的为集合中的每个项创建了一个新函数吗?它可以简单地存储函数并调用它n次,我想是的,让我将该语句改为“我认为它创建了一个新函数”,因为我不确定…:-)我确信上面的代码确实为集合中的每个项目创建了一个新函数。您可以在前面定义函数并执行
someArray.each(functionName)每个
的工作原理与jQuery中的相同,这意味着
var people = [ .. ];
for(var i /* 1 */ = 0; i /* 2 */ < people.length; i++ /* 3 */) {
    people[i /* 4 */].updateRecords();
    people[i /* 5 */].increaseSalary();
}
people.forEach(function(person) {
    person.updateRecords();
    person.increaseSalary();
});
if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}