Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

eslint-plugin-no-for-each

0.1.14 • Public • Published

eslint-plugin-no-for-each

What it does? Fix forEach, for in, and for of loops.

Before:

image

After:

['error', 'cache-length'] image

['error'] image

https://jsperf.com/foreach-vs-for-loop-vs-for-in-vs-for-of-vs-babel-for-of

Installation

You'll first need to install ESLint:

$ npm i eslint --save-dev

Next, install eslint-plugin-no-for-each:

$ npm install eslint-plugin-no-for-each --save-dev

Note: If you installed ESLint globally (using the -g flag) then you must also install eslint-plugin-no-for-each globally.

Configuration

Add no-for-each to the plugins section of your .eslintrc configuration file. Then configure the rules you want to use under the rules section.

  • default: 1 or ["error"]
  • cache-length: 2
{
  "plugins": [
    "no-for-each"
  ],
  "rules": {
    "no-for-each/no-for-each": 2,
    "no-for-each/no-for-of": 2,
    "no-for-each/no-for-in": 2,
  }
}

two additional WIP rules

"rules"{
  "...": "...",
  "no-for-each/cache-for-length": 2,
  "no-excessive-blank-lines": 2
}

Resources

known bugs

  • properly parse Object.keys(apples).forEach(apple => delete apples[apple]) because it replaces apple with new var, but not apples so it leaves the s
  • nested loops, will do this soon
  • truncating body at some point

jsperf

var testData = [];
for (var i = 0; i < 100; i++) {
  testData.push(i);
}
 
// forEach
var res = 0;
testData.forEach(function(x) {
  res += x;
});
 
// for
var res = 0;
for (var i = 0; i < testData.length; i++) {
  res += testData[i];
}
 
// for optimized
var res = 0;
for (var i = 0, len = testData.length; i < len; i++) {
  res += testData[i];
}
 
// reduce
var res = testData.reduce(function(sum, x) {
  return sum + x;
}, 0);
 
 
// while
var res = 0;
var i = testData.length;
while (i--) {
    res += testData[i];
}
 
// for in
var res = 0;
for (var data in testData) {
  res += testData[i];
}
 
 
// for of
var res = 0;
for (var data of testData) {
  res += testData[i];
}
 
 
// for of babel
var res = 0;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
 
try {
  for (var _iterator = testData[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    var value = _step.value;
 
    console.log(value);
  }
} catch (err) {
  _didIteratorError = true;
  _iteratorError = err;
} finally {
  try {
    res += testData[i];
    if (!_iteratorNormalCompletion && _iterator.return) {
      _iterator.return();
    }
  } finally {
    if (_didIteratorError) {
      throw _iteratorError;
    }
  }
}

@NOTES:


could keep option cache-length but since we are using an object, seems silly to call object.keys 2x

we do not use body.body because

    1. not always there
    1. we want to keep curly braces (or lack of from the source

(when it has proper configs and has large files to test, then release 1.0.0)

@TODO:

  • add config option for cache-length-inside-loop (var i = 0, len = varName.length; ...)
  • recommend let => const rule
  • add large js files to test failed fixing & safety
  • isDev | isTest helper funcs
  • ^ add args in tests for devtest
  • comment on readmes
  • move todos to issues
  • use type in the left of the loop such as const, let, var
  • o.hasOwnProperty for for in/of
  • make a guide how to make an eslint plugin

Install

npm i eslint-plugin-no-for-each

DownloadsWeekly Downloads

158

Version

0.1.14

License

ISC

Last publish

Collaborators

  • avatar