0.1.14 • Published 7 years ago

eslint-plugin-no-for-each v0.1.14

Weekly downloads
167
License
ISC
Repository
-
Last release
7 years ago

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
  • 2) 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
  • (lower priority) make a guide how to make an eslint plugin
0.1.14

7 years ago

0.1.13

7 years ago

0.1.12

7 years ago

0.1.11

7 years ago

0.1.10

7 years ago

0.1.9

7 years ago

0.1.8

7 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago

0.0.10

7 years ago

0.0.9

7 years ago

0.0.8

7 years ago

0.0.7

7 years ago

0.0.6

7 years ago

0.0.5

7 years ago

0.0.4

7 years ago

0.0.3

7 years ago

0.0.2

7 years ago