现在,在新项目中,他们使用_.foreach()循环来迭代数组.
我想知道的是,和_.foreach()的原生打字稿之间是否有性能差异?
我在jsperf中创建了一个小测试,他们缝合的速度或多或少完全相同……
https://jsperf.com/foreach-vs-forof/12
TypeScript For
for (let num: string of list){ console.log(num); }
在JavaScript中
var list = "9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9".split(); //Transpiled TypeScript for of | **19,937 ±5.04% for (var _i = 0, list_1 = list; _i < list_1.length; _i++) { var num = list_1[_i]; console.log("" + num); } //lodash | 20,520 ±1.22% _.forEach(list, function(item) { console.log("" + item) });
Imho我更喜欢TypeScript的“原生”,因为它对我来说更具可读性.
你们建议使用什么?还有其他要点用于或更好的_.forEach
除了我的阅读之外,我没有任何打字稿的经验,但我对ES6 / ES2015有相当多的经验.因为过去和现在仍然是最终确定的ES2015规范的一部分.我将从MDN上阅读 this篇文章.以下是for和forEach的一些相似之处和不同之处(这些只是我目前发现和了解的内容):
> lodash中的forEach适用于Arrays,Objects或者集合
字符串.
> native forEach适用于数组,映射和集合.
> for for all on all Iterables:Arrays,Strings,TypedArrays,
地图,集合,DOM集合和生成器.
我会读这一章从Exploring ES6(探索ES6是一个伟大的阅读.这是非常彻底的,它是免费的在线为好.)从它的一些东西,站出来给我不同的关于那个都不在的forEach.
break and continue work inside for-of loops
break和continue不会在forEach中暴露.你可以在forEach中继续使用的最接近的事情是使用return,这实际上几乎是一样的.至于休息,我看不到其他选择(但不要打折lodash,因为大多数lodash的库已经涵盖了大多数需要休息的东西,如找到并返回单个项目).
使用在ES2017中到达的Object.entries,您甚至可以轻松准确地迭代对象拥有的可枚举属性和值.如果你现在想要使用它,你可以使用其中一个polyfill here.这是一个看起来像什么的例子.
var obj = {foo: "bar", baz: "qux"}; for (let x of Object.entries(obj)) { // OK console.log(x); // logs ["foo", "bar"] then ["baz", "qux"] }
和here是我写的快速填充的实现.你通常也会使用数组解构,它会将键和值分成它自己的变量,如下所示:
var obj = {foo: "bar", baz: "qux"}; for (let [key, val] of Object.entries(obj)) { // OK console.log(key + " " + val); // logs "foo bar" then "baz qux" }
forEach的第一个参数默认为你在for或for循环中得到的功能类型,这是一件好事.我的意思是,如果变量内部存在任何异步,那么该迭代的范围将仅限于该循环的特定部分. forEach的这个属性与let没有关系,但是在JavaScript中有函数的范围和闭包,另一种选择是由于它们不是块作用域.例如,看看使用var时会发生什么:
const arr = [1,2,3,4,5,6,7,8,9]; for(var item of arr) { setTimeout(() => { console.log(item); }, 100); }
与使用let或foreach时相反.
const arr = [1,2,3,4,5,6,7,8,9]; const timeout = 100; console.log('for of'); for(let item of arr) { setTimeout(() => { console.log(item); }, timeout); } setTimeout(() => { console.log('foreach'); arr.forEach((item) => { setTimeout(() => { console.log(item); }, timeout); }) }, timeout*arr.length);
同样,我将注意使用var和使用let或foreach之间的区别.不同的是,VAR的变量被吊起到功能范围的顶部(或文件,如果它不是一个函数),然后将值重新分配对于整个范围,因此该循环到达终点,并最后一次分配项目然后每个settimeout函数记录最后一项.而let和foreach变量项不会被覆盖,因为item的范围是块(当使用let时)或函数(当使用foreach时).
在forEach和for之间你只需要决定哪一个最适合当前的工作(例如你需要休息或需要使用地图,集合或生成器用于).除此之外,我觉得没有特别强烈的理由,无论是收藏还是其核心功能.此外,当处理可以使用forEach或者它的集合时,主要取决于个人偏好,因为它们以大致相同的速度执行相同的操作(并且根据解释器,速度可以随时改变).我觉得lodash的特殊优势在于它的其他各种功能,这些功能实际上可以节省你自己编写代码的大量时间,如map,reduce,filter和find.因为你觉得写作最舒服我建议你继续这样写,但是一旦你开始使用其他功能在lodash中写作,你可能会开始觉得用Lodash方式写它更舒服.
编辑:
查看代码,我发现列表创建时出错.最后你只有.split(),你应该有.split(“,”).您正在创建一个整个字符串的长度为1的列表,并在该字符串上迭代一次,这就是为什么基准测试标记非常相似.我重新考试了.他们是Here.我仍然不会担心它每次运行时的性能变化.