Home >Web Front-end >JS Tutorial >In-depth exploration of the efficiency issues and related optimization of for loops in JavaScript_javascript skills
Underscore.js library
How many loops have you written in one day (week)?
var i; for(i = 0; i < someArray.length; i++) { var someThing = someArray[i]; doSomeWorkOn(someThing); }
It's harmless, of course, but it's ugly and weird and not really something to complain about. But this way of writing is too banal.
var i, j; for(i = 0; i < someArray.length; i++) { var someThing = someArray[i]; for(j = 0; j < someThing.stuff.length; j++) { doSomeWorkOn(someThing.stuff[j]); } }
You're extending bad code, and before you throw a bunch of ifs, you're already insane.
I haven't written a loop in two years.
"What are you talking about?"
It's true, a bad joke. Actually not none (ok, I did write a few), because I don’t write loops and my code is easier to understand.
How?
_.each(someArray, function(someThing) { doSomeWorkOn(someThing); })
Or better yet:
_.each(someArray, doSomeWorkOn);
This is what underscorejs does. Clean, simple, readable, short, no intermediate variables, no tons of semicolons, simple and very elegant.
Here are some more examples.
var i, result = []; for(i = 0; i < someArray.length; i++) { var someThing = someArray[i]; // 打到这,我已经手疼了 if(someThing.isAwesome === true) { result.push(someArray[i]); } }
Again, a typical use case for wasting time using loops. Even though these sites promote anti-smoking and vegetarianism, I feel outraged when I see these codes. Look at the simple way to write it.
var result = _.filter(someArray, function(someThing) { return someThing.isAwesome === true; })
Like the name of filter in underscore, just 3 lines of code can give you a new array.
Or do you want to convert these arrays into another form?
var result = _.map(someArray, function(someThing) { return trasformTheThing(someThing); })
The above three examples are sufficient in daily life, but these functions are not enough for underscore to be put on the table.
var grandTotal = 0, somePercentage = 1.07, severalNumbers = [33, 54, 42], i; // don't forget to hoist those indices; for(i = 0; i < severalNumbers.length; i++) { var aNumber = severalNumbers[i]; grandTotal += aNumber * somePercentage; }
underscore version
var somePercentage = 1.07, severalNumbers = [33, 54, 42], grandTotal; grandTotal = _.reduce(severalNumbers, function(runningTotal, aNumber) { return runningTotal + (aNumber * somePercentage); }, 0)
This may seem a bit strange at first. I checked the documentation about reduce and found out about its existence. Since I refuse to use loops, it's my first choice. The above things are just an introduction. The underscorejs library also has a lot of awesome functions.
30 days no use cycle challenge.
Don’t use any loops for the next 30 days. If you see a bunch of nasty and rough stuff, replace them with each or map. Use a little more reducing.
You need to note that Underscore is the gateway to functional programming. A visible, invisible way. A good way to go.
OurJS Note* Modern browsers currently support each, filter, map, and reduce methods, but the underscore library can achieve compatibility with older versions of IE. The following is an example written using ES5 native methods:
[3,4,5,3,3].forEach(function(obj){ console.log(obj); }); [1,2,3,4,5].filter(function(obj){ return obj < 3 }); [9,8,5,2,3,4,5].map(function(obj){ return obj + 2; }); [1,2,3,4,5].reduce(function(pre, cur, idx, arr) { console.log(idx); //4 个循环: 2-5 return pre + cur; }); //15 //sort方法同样很有用 [9,8,5,2,3,4,5].sort(function(obj1, obj2){ return obj1 - obj2; });
for in and for loop
Someone pointed out that the efficiency of for in is much lower than that of for loop. Now let's test the efficiency of using for in, for loop and forEach in different browsers when processing large arrays.
At present, most open source software will cache the array length in the for loop, because the common view is that some browsers Array.length will recalculate the array length every time, so temporary variables are usually used to store the array length in advance, such as:
for (var idx = 0, len = testArray.length; idx < len; idx++) { //do sth. }
We will also test the performance difference between caching and no caching.
Also add a summation operation in each test loop to show that it is not an empty loop.
for (var idx = 0, len = testArray.length; idx < len; idx++) { //do sth. }
We will also test the performance difference between caching and no caching.
Also add a summation operation in each test loop to show that it is not an empty loop.
The test code is as follows, click Run to view
HTML code
<h4 id="browser"></h4> <table id="results" class="table"></table>
JavaScript code
function () { //准备测试数据, 有200万条数据的大数组 var testArray = [] , testObject = {} , idx , len = 2000000 , tmp = 0 , $results = $("#results") , $browser = $("#browser") ; $browser.html(navigator.userAgent); $results.html(''); for (var i = 0; i < len; i++) { var number = Math.random(); //若希望加快运算速度可使用取整:Math.random() * 10 | 0 testArray.push(number); testObject[i] = number; } $results.append('<tr><th>测试代码</th><th>计算结果</th><th>所需时间,毫秒</th></tr>'); //测试函数 var test = function(testFunc) { var startTime , endTime , result ; startTime = new Date(); tmp = 0; testFunc(); endTime = new Date(); //计算测试用例(Test Case)运行所需要的时间 result = endTime - startTime; $results.append('<tr><td><pre class="brush:php;toolbar:false">{0}
Run [Please wait a moment]
Test results
The test results may vary depending on the calculation. This is a summary of the test results of Firefox, Chrome, and IE running on my machine.
The following are several observed conclusions