{"_id":"@dabh/eslint-config-populist","_rev":"3-f3b48144971a1cd1b050f6f150ff794a","name":"@dabh/eslint-config-populist","dist-tags":{"latest":"4.4.0"},"versions":{"4.3.0":{"name":"@dabh/eslint-config-populist","version":"4.3.0","keywords":["styleguide","javascript","style-guide","common-style","standard style","standard"],"author":{"name":"Charlie Robbins","email":"charlie.robbins@gmail.com"},"license":"MIT","_id":"@dabh/eslint-config-populist@4.3.0","maintainers":[{"name":"dabh","email":"dabh@alumni.stanford.edu"}],"homepage":"https://github.com/indexzero/populist-style","bugs":{"url":"https://github.com/indexzero/populist-style/issues"},"bin":{"populist":"bin/eslint-autofix.js"},"dist":{"shasum":"4089a31ede2e6e137b2c674d589540172bcded5c","tarball":"https://registry.npmjs.org/@dabh/eslint-config-populist/-/eslint-config-populist-4.3.0.tgz","fileCount":5,"integrity":"sha512-CDIY1MTAyJWnHdE/NGjZWxe2O2zziAgvI5WtmZDCK3j2bjVF0m1Z9XZ0RiFu3dJTKQ5xqCu82fEM9k0osYnFnw==","signatures":[{"sig":"MEQCIGvr7S9I3LXQV68unXfymj6q3ns5hEhGqXbr+x2CwAgYAiAtVXvjB5jJQc0V/+TyWtB6rPH2HVHVg5a7smXgbL6YXA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":32414,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh/rm+CRA9TVsSAnZWagAAWpoP/RxS4e5mleGF846/Zi1U\n0vK8bC/7EZTu6ArgSvC957VjbWVR1ObRVx49aMCQ6cDRaceCzvJoJvy4GfQr\nfKUo7dtqlmNmUc7WEwCEN625OmCNmU+wmRRR4CCo7NnlqUlgEgXx1yxHyvKU\np4Rxf4VDVx+5L/Im5kGouOBHKkFHIZVDBaWGe3KcIqaLChDxbuiPU8zAh5dw\nRZaS6U/YB/9izcgw8/FiPzatALenkky6WFBcSDAJP0il97Xpk0MyGQHlN5mu\nVdtchOEX/VHgq/3xMXsoID8L2R0+C0IPthgSTSvqBY88gcz4Hao1H3qw16EQ\n12iHefew+zN4Ycl+AfdIHcURxmqTtRkZbJCxv8axpLS4Et4u9AjxiMD0A79N\nBHhJGUTmflf2Ii6rakktfnFpQ3UjwoiUddiYsxa0vOXajHXriU6v2az9PPu+\nKWOdJHuJqfTx0QGGF3LL3aiFAz6BhDZp251TEXoeDeBLx2cb7jngoUEFgjEd\nxg+goLI2JHFQ+2bF9tm4AHP5g3CI6tYO16oeOZ5ecFsbPDpGcA5PhA5I7TlU\nr/CVtBthWFqLH+nRsTzmH8666B/AZG4lyXhZyBYuG5b+K6UjToqbGBu08iVj\n1k65zNgI5r2iFH7lLVb/XXOHj7YwsEu4NwJdGCOC1z2k+0Abwq9EO8rk7i6q\nrwBs\r\n=0x8a\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"990cc3155e9b8180265302f59a329d2d4d8941e9","_npmUser":{"name":"dabh","email":"dabh@alumni.stanford.edu"},"repository":{"url":"git+https://github.com/indexzero/populist-style.git","type":"git"},"_npmVersion":"8.4.1","description":"A (one day) auto-updating style at the mercy of the people, and only the people.","directories":{},"_nodeVersion":"14.19.0","dependencies":{"eslint":"^8.8.0","eslint-find-rules":"^4.1.0","eslint-plugin-json":"^3.1.0","eslint-plugin-mocha":"^10.0.3"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/eslint-config-populist_4.3.0_1644083646593_0.8635984865255162","host":"s3://npm-registry-packages"}},"5.0.0":{"name":"@dabh/eslint-config-populist","version":"5.0.0","keywords":["styleguide","javascript","style-guide","common-style","standard style","standard"],"author":{"name":"Charlie Robbins","email":"charlie.robbins@gmail.com"},"license":"MIT","_id":"@dabh/eslint-config-populist@5.0.0","maintainers":[{"name":"dabh","email":"dabh@alumni.stanford.edu"}],"homepage":"https://github.com/winstonjs/populist-style","bugs":{"url":"https://github.com/winstonjs/populist-style/issues"},"dist":{"shasum":"c0b40abbd172637dace3c96d0d422cfe40e3df72","tarball":"https://registry.npmjs.org/@dabh/eslint-config-populist/-/eslint-config-populist-5.0.0.tgz","fileCount":4,"integrity":"sha512-e6uFqJFY9TCEc8uuhFXjh3WLPos4eU/2R/b/tmR09QSCVIZNR/XIG58ImEZ1HTS5cDk52xZL4EpkRJuqG/SJoA==","signatures":[{"sig":"MEUCIQD1OPdl9qyGrq6+/dt+ZWQfFKHlapZIrT41R5z1+9PZWgIgC3Q3wdncYAqL3xfBTLuZHy2ffz9EPgKBTiWBXtFrQYk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":31168,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh/sNnCRA9TVsSAnZWagAAb4sQAJ5iSIlYXW/bEYF9xRe+\nK+jSmGQoeCnyyQDvcdC6tfudbyqqhKjtRRmakOLGs0BA+mndD9E5WERxK5AG\nSch7MPnVvoo0lYOeuA0JeuVwLklo62pYmf5/MjKvALe2yshfgOOMnB7r65/k\np6Sxj0gSqkjRhyIBICHWGZIDijdeU9eGSEzYD/0Q3map6ay/YFNoFHa/m7Ha\nKdeH7z+CetCSqyJKhM7Hg9pshne3xoZaZfBKKsWtbfkSEfDez0wXRXxyxCTb\nZJihms6ZnX1zWjZQ8yIfYu3kkJgobhBry3sWH4NPTloPWi/MRNhUPaWuB50l\nY8PQvif+56DQwVFPPwG4m+eLSxqxqbeeoTNRMAuFeASNZogifCP3l5ZUVUiJ\naO9ldqOAUSovK7UNCyByBzxHITKldbK52Uy8H7DTV+HYfRfqUH9gBX380wmZ\nBXROjM4xOjjN+ifXxW1yJEMO0dKm2UmxpzFVmZdgbiaxHiVQmx9QW3Ldj2Ri\nb3/qQwrplLia67twWKeTfYOnVSJdAPX/paAVIMbpQI8kWh4XHmVIoJCllhTn\nhtb9Jomda46j1oSOyzmgTPzS5g1bKkjDH5fYKlaQxfHwglbLMwQmOJIuvM99\nvAQTAFEz72I74mrkoINT0iqwigrfGyfucupOSYb/VQEOz4GxeSjhy2jprSCd\n1nH5\r\n=kXeQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"39cce0b448b61cc25c55a4e562d536e82f5cfce1","_npmUser":{"name":"dabh","email":"dabh@alumni.stanford.edu"},"repository":{"url":"git+https://github.com/winstonjs/populist-style.git","type":"git"},"_npmVersion":"8.4.1","description":"A (one day) auto-updating style at the mercy of the people, and only the people.","directories":{},"_nodeVersion":"14.19.0","dependencies":{"eslint-find-rules":"^4.1.0","eslint-plugin-json":"^3.1.0","eslint-plugin-mocha":"^10.0.3"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^8.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-populist_5.0.0_1644086119602_0.6635978952818944","host":"s3://npm-registry-packages"}},"4.4.0":{"name":"@dabh/eslint-config-populist","version":"4.4.0","description":"A (one day) auto-updating style at the mercy of the people, and only the people.","main":"index.js","repository":{"type":"git","url":"git+https://github.com/winstonjs/populist-style.git"},"scripts":{"test":""},"keywords":["styleguide","javascript","style-guide","common-style","standard style","standard"],"author":{"name":"Charlie Robbins","email":"charlie.robbins@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/winstonjs/populist-style/issues"},"homepage":"https://github.com/winstonjs/populist-style","peerDependencies":{"eslint":">=8.0.0"},"dependencies":{"eslint-find-rules":"^4.1.0","eslint-plugin-json":"^4.0.0","eslint-plugin-mocha":"^10.4.3"},"_id":"@dabh/eslint-config-populist@4.4.0","gitHead":"719a2b24ca6794094dec3331417cd79c8e65f588","_nodeVersion":"18.18.2","_npmVersion":"10.8.1","dist":{"integrity":"sha512-lRS72lonXi7cBjOcRKQMhfXwogRnaVsbm46FW/fQGXDGhCmKdykw6o0vpG4QVr6uDovoVh1ypXvFZiiu3GYwKQ==","shasum":"f4708a645496f58fcbdb6e2ba723c4159adb0033","tarball":"https://registry.npmjs.org/@dabh/eslint-config-populist/-/eslint-config-populist-4.4.0.tgz","fileCount":4,"unpackedSize":31123,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYkgVN8qYHV2sKAIR3zvApUMVAjT7N1vhx3HTD4PasLgIhALdwpDYd5zB85Brg0tcTEY2cYlaRxG4d5tuHod4oJi+1"}]},"_npmUser":{"name":"dabh","email":"dabh@alumni.stanford.edu"},"directories":{},"maintainers":[{"name":"dabh","email":"dabh@alumni.stanford.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/eslint-config-populist_4.4.0_1720644285096_0.8360407582503051"},"_hasShrinkwrap":false}},"time":{"created":"2022-02-05T17:54:06.543Z","modified":"2024-07-10T20:44:45.442Z","4.3.0":"2022-02-05T17:54:06.744Z","5.0.0":"2022-02-05T18:35:19.755Z","4.4.0":"2024-07-10T20:44:45.271Z"},"bugs":{"url":"https://github.com/winstonjs/populist-style/issues"},"author":{"name":"Charlie Robbins","email":"charlie.robbins@gmail.com"},"license":"MIT","homepage":"https://github.com/winstonjs/populist-style","keywords":["styleguide","javascript","style-guide","common-style","standard style","standard"],"repository":{"type":"git","url":"git+https://github.com/winstonjs/populist-style.git"},"description":"A (one day) auto-updating style at the mercy of the people, and only the people.","maintainers":[{"name":"dabh","email":"dabh@alumni.stanford.edu"}],"readme":"# Populist Style for JavaScript\n\nA (one day) auto-updating style at the mercy of the people, and only the\npeople.\n\nToday it is still a bespoke set of rules. One has to have goals, no? The copy\nbelow is unfortunately a bit out of date compared to the latest `eslint` rules\nin `index.js`. They remain because reusing the English copy is very likely\neven with new and/or slightly different rules.\n\n> If you have comments on this or **disagree about rules** then\n> please reach out to me directly. I want to hear it!\n\n## Table of Contents\n\n**_Basics_**\n* [Compliance Levels](#compliance-levels)\n* [Ground Rules](#ground-rules)\n* [Semicolons](#semicolons)\n* [Braces](#braces)\n\n**_Identifiers and Primitives_**\n* [Naming Contentions](#naming-conventions)\n* [Variable Declarations](#variable-declarations)\n* [Objects](#objects)\n* [Arrays](#arrays)\n* [Strings](#strings)\n* [Comments](#code-comments)\n* [Constructors](#constructors)\n\n**_Statements and Techniques_**\n* [Control-flow](#control-flow)\n* [Functions](#function)\n* [Conditionals](#conditionals)\n* [Type Casting & Coercion](#type-casting--coercion)\n* [Ternary Operators](#ternary-operators)\n* [Errors](#errors)\n* [Exports](#exports)\n* [Async](#async-programming)\n\n> [Attribution](#attribution)\n\n## Compliance Levels\n\n### GOOD and BAD\n* **always / must**: This is **_mandatory_**. _Seriously_\n* **never / must not**: Don't **_ever_** do this. Seriously.\n\n### OK\n* **should**: **_Try to_** do this. It is encouraged but not strictly enforced.\n* **should not**: **_Try not to_** do this. It is discouraged but not prohibited.\n\n## Ground Rules\n\n- **RULE**: **Always** 2-space soft indents (no tabs)\n- **RULE**: **Always** semicolons (with [one exception](#semicolons)).\n- **RULE**: **Never use comma first**\n- **RULE**: **Never use** `()` around statements like `typeof` or `delete`.\n\n## Semicolons\n\n- **RULE**: Semicolons `;` **must** be added at the end of every statement, **except** when the next character is a closing bracket `}`. In that case, they may be omitted.\n\n``` js\n//\n// GOOD\n//\nvar f = function add(a, b) {\n  if (a == b) { return a * 2 }   // No `;` here.\n  return a + b;\n};\n```\n\n``` js\n//\n// BAD\n//\nvar f = function add (a, b) {\n  return a + b\n}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Braces\n\n- **RULE**: Braces **must** be used in all circumstances. They **may** be used on a single line around simple statements.\n\n``` js\n//\n// GOOD\n//\nif (x) { return true }\n```\n\n``` js\n//\n// BAD\n//\nif (x)\n  while (1)\n    i ++;\nelse\n  //...\n```\n\n``` js\n//\n// BAD\n//\nif (x) return true;\n```\n\n``` js\n//\n// BAD\n//\nif (x)\n  return true;\n```\n\n<hr>\n\n- **RULE**: Opening Braces **must never** be on a line of their own.\n- **Rule**: Closing braces **must never** be followed by a conditional statement\n\n> Vertical screen space is precious, and ease of scanning code\n> is more previous.\n\n``` js\n//\n// GOOD\n//\nif (x) {\n  return true;\n}\nelse {\n  return false;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (x)\n{\n  return true;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (x) {\n  return true; }\n```\n\n``` js\n//\n// BAD\n//\nif (x) {\n  return true;\n} else {\n  return false\n}\n```\n\n<hr>\n\n- **RULE**: Closing Braces **must always** be on a line of their own unless they also start on that line.\n\n> This makes it easy to see the end of a function or statement\n\n``` js\n//\n// GOOD\n//\nreturn callback && callback({ foo: bar });\n```\n\n``` js\n//\n// GOOD\n//\nreturn callback && callback({\n  foo: bar\n});\n```\n\n``` js\n//\n// BAD\n//\nreturn callback && callback({\n  foo: bar });\n```\n\n``` js\n//\n// BAD\n//\nreturn callback && callback({ foo: bar\n  });\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Naming Conventions\n\n- **RULE**: Avoid single letter names. Be descriptive with your naming.\n\n``` js\n//\n// BAD\n//\nfunction q() {\n  // ...stuff...\n}\n\n//\n// GOOD\n//\nfunction query() {\n  // ..stuff..\n}\n```\n\n<hr>\n\n- **RULE**: Use camelCase when naming objects, functions, and instances\n\n``` js\n//\n// BAD\n//\nvar OBJEcttsssss = {};\nvar this_is_my_object = {};\nvar this-is-my-object = {};\nfunction c() {};\nvar u = new user({\n  name: 'Bob Parr'\n});\n\n//\n// GOOD\n//\nvar thisIsMyObject = {};\n\nfunction thisIsMyFunction() {};\n\nvar user = new User({\n  name: 'Bob Parr'\n});\n```\n\n<hr>\n\n- **RULE**: Use PascalCase when naming constructors or classes\n\n``` js\n// BAD\nfunction user(options) {\n  this.name = options.name;\n}\n\nvar bad = new user({\n  name: 'nope'\n});\n\n// GOOD\nfunction User(options) {\n  this.name = options.name;\n}\n\nvar good = new User({\n  name: 'yup'\n});\n```\n\n<hr>\n\n- **RULE**: Use a leading underscore `_` when naming private properties\n\n``` js\n// BAD\nthis.__firstName__ = 'Panda';\nthis.firstName_ = 'Panda';\n\n// GOOD\nthis._firstName = 'Panda';\n```\n\n<hr>\n\n- **RULE**: Saved references to `this` (which is a prototypal object) **must** use `self`.\n\n``` js\nfunction User (options) {\n  this.setup();\n}\n\n//\n// GOOD\n//\nUser.prototype.setup = function () {\n  var self = this;\n\n  setTimeout(function () {\n    self.ready = true\n  }, 1000);\n};\n\n//\n// BAD\n//\nUser.prototype.setup = function () {\n  var that = this;\n\n  setTimeout(function () {\n    that.ready = true\n  }, 1000);\n};\n```\n\n<hr>\n\n- **RULE**: Saved references to `this` (which is an arbitrary scope) **should** use `that`.\n\n``` js\n//\n// BAD\n//\nfunction () {\n  var self = this;\n  return function() {\n    console.log(self);\n  };\n}\n\n//\n// BAD\n//\nfunction () {\n  var _this = this;\n  return function() {\n    console.log(_this);\n  };\n}\n\n//\n// GOOD\n//\nfunction () {\n  var that = this;\n  return function() {\n    console.log(that);\n  };\n}\n```\n\n<hr>\n\n- **RULE**: Functions **should** be named. This is helpful for stack traces.\n\n``` js\n//\n// OK\n//\nvar log = function(msg) {\n  console.log(msg);\n};\n\n//\n// GOOD\n//\nvar log = function log(msg) {\n  console.log(msg);\n};\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Variable declarations\n\n- **RULE**: Variables **must** always be declared, prior to use.\n- **RULE**: Variable declarations **must** appear at the top of functions, and not inside other blocks. The exception is *for* loops.\n\n> Variable declarations are moved up to the top of the function\n> scope anyway, so that's where they belong.\n\n``` js\n//\n// GOOD\n//\nfunction (a, b) {\n  var k;\n\n  if (a == b) {\n    k = true;\n  }\n  //...\n}\n\nfor (var i = 0; i < l; i ++) {\n  //...\n}\n```\n\n``` js\n//\n// BAD\n//\nfunction (a, b) {\n  if (a == b) {\n    var k = true;\n  }\n  //...\n}\n```\n\n<hr>\n\n- **RULE**: Variables **must** always align when they are declared\n\n> This makes it easy to scan what is declared in a single block.\n\n``` js\n//\n// GOOD\n//\nvar bazz,\n    foo,\n    bar;\n```\n\n``` js\n//\n// BAD\n//\nvar bazz,\n  foo,\n  bar;\n```\n\n<hr>\n\n- **RULE**: Declare unassigned variables last.\n\n> This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables.\n\n``` js\n//\n// BAD\n//\nvar i, len, dragonball,\n    items = getItems(),\n    goSportsTeam = true;\n\n//\n// BAD\n//\nvar i, items = getItems(),\n    dragonball,\n    goSportsTeam = true,\n    len;\n\n//\n// GOOD\n//\nvar items = getItems(),\n    goSportsTeam = true,\n    dragonball,\n    length,\n    i;\n```\n\n<hr>\n\n- **RULE**: Variables **should** always be declared in decreasing length.\n\n> This also makes it easier to scan what is declared in a single block (trust me).\n\n``` js\n//\n// GOOD\n//\nvar reallyLongVar,\n    shorterVar,\n    fooBar,\n    foo;\n```\n\n``` js\n//\n// BAD\n//\nvar fooBar,\n    shorterVar,\n    foo,\n    reallyLongVar;\n```\n\n<hr>\n\n- **RULE**: Variable assignments **must** come before declarations.\n- **RULE**: Variable assignments **should** align **when convenient** depending on additional length.\n\n> This also makes it easier to scan what is declared in a single block (trust me).\n\n``` js\n//\n// GOOD\n//\nvar reallyLongVar = 10e3,\n    shorterVar    = 5e2,\n    fooBar        = 'foobar',\n    foo;\n```\n\n``` js\n//\n// OK\n//\nvar reallyLongVar = 10e3,\n    shorterVar = 5e2,\n    fooBar = 'foobar',\n    foo;\n```\n\n``` js\n//\n// BAD\n//\nvar foo,\n    reallyLongVar = 10e3,\n    shorterVar = 5e2,\n    fooBar = 'foobar';\n```\n\n<hr>\n\n- **RULE**: Multi-line object literals **must be** assigned outside of multi-line variable declaration blocks.\n\n> It's what god would have wanted.\n\n``` js\n//\n// GOOD\n//\nvar obj  = { list: [], expired: false },\n    bazz = 100,\n    foo,\n    bar;\n```\n\n``` js\n//\n// GOOD\n//\nvar bazz = 100,\n    foo,\n    bar,\n    obj;\n\nobj  = {\n  list: [],\n  expired: false\n};\n```\n\n``` js\n//\n// BAD\n//\nvar obj  = {\n  list: [],\n  expired: false\n},\n    bazz = 100,\n    foo,\n    bar;\n```\n\n``` js\n//\n// BAD\n//\nvar bazz = 100,\n    foo,\n    bar,\n    obj = {\n      list: [],\n      expired: false\n    };\n```\n\n<hr>\n\n- **RULE**: Assignment depending on multi-line functions or multiple functions **must be** assigned outside of multi-line variable declaration blocks.\n\n``` js\n//\n// GOOD\n//\nvar memo = list.filter(function (i) { return i < 10 }),\n    bazz = 100,\n    foo,\n    bar;\n```\n\n``` js\n//\n// GOOD\n//\nvar bazz = 100,\n    memo,\n    foo,\n    bar;\n\nmemo = list.filter(function (i) {\n  return i < 10;\n}).filter(Boolean);\n```\n\n``` js\n//\n// BAD\n//\nvar memo = list.filter(function (i) {\n  return i < 10\n}),\n    bazz = 100,\n    foo,\n    bar;\n```\n\n``` js\n//\n// BAD\n//\nvar bazz = 100,\n    foo,\n    bar,\n    memo = list.filter(function (i) {\n      return i < 10;\n    }).filter(Boolean);\n```\n\n``` js\n//\n// BAD\n//\nvar bazz = 100,\n    foo,\n    bar,\n    memo = list.filter(function (i) { return i < 10 })\n      .filter(Boolean);\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Objects\n\n- **RULE**: Single line object **must** have a trailing space after `{` and a leading space before `}`.\n\n``` js\n//\n// BAD\n//\nvar foo = {bar: 1};\n```\n\n``` js\n//\n// BAD\n//\nreturn {bar: 1};\n```\n\n``` js\n//\n// GOOD\n//\nvar foo = { bar: 1 };\n```\n\n``` js\n//\n// GOOD\n//\nreturn { bar: 1 };\n```\n\n<hr>\n\n- **RULE**: Properties in objects **must** be followed by a `:`\n\n``` js\n//\n// BAD\n//\nvar foo = { bar:1 };\n```\n\n``` js\n//\n// BAD\n//\nvar foo = {\n  bar  : 1,\n  bazz : 1\n};\n```\n\n``` js\n//\n// GOOD\n//\nvar foo = { bar: 1 };\n```\n\n``` js\n//\n// GOOD\n//\nvar foo = {\n  bar: 1,\n  bazz: 1\n};\n```\n\n``` js\n//\n// GOOD\n//\nvar foo = {\n  bar:  1,\n  bazz: 1\n};\n```\n\n<hr>\n\n- **RULE**: Multi-line assignment statements **inside an object literal** are **encouraged.**\n\n> Reduces the number of variables managed and object creation is cheap.\n\n``` js\n//\n// GOOD\n//\nreturn {\n  foos: list.filter(function (i) {\n    return i.type === 'foo';\n  }),\n  bars: list.filter(function (i) {\n    return i.type === 'bar';\n  })\n}\n```\n\n<hr>\n\n- **RULE**: Use the literal syntax for object creation.\n\n``` js\n//\n// BAD\n//\nvar item = new Object();\n\n//\n// GOOD\n//\nvar item = {};\n```\n\n- Using [reserved words](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words) is fine as _it is valid Javascript._\n\n``` js\n//\n// OK\n//\nvar superman = {\n class: 'superhero',\n default: { clark: 'kent' },\n private: true\n};\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Arrays\n\n- **RULE**: Use the literal syntax for array creation\n\n``` js\n//\n// BAD\n//\nvar items = new Array();\n\n// GOOD\nvar items = [];\n```\n\n<hr>\n\n- **RULE**: If you don't know array length use Array#push.\n\n``` js\nvar someStack = [];\n\n//\n// BAD\n//\nsomeStack[someStack.length] = 'abracadabra';\n\n//\n// GOOD\n//\nsomeStack.push('abracadabra');\n```\n\n<hr>\n\n- **RULE**: When you need to copy an array use Array#slice. [jsPerf](http://jsperf.com/converting-arguments-to-an-array/7)\n\n``` js\nvar len = items.length,\n    itemsCopy = [],\n    i;\n\n//\n// BAD\n//\nfor (i = 0; i < len; i++) {\n  itemsCopy[i] = items[i];\n}\n\n//\n// GOOD\n//\nitemsCopy = items.slice();\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Strings\n\n- **RULE**: Use single quotes `''` for strings\n\n``` js\n//\n// BAD\n//\nvar name = \"Bob Parr\";\n\n//\n// GOOD\n//\nvar name = 'Bob Parr';\n\n//\n// BAD\n//\nvar fullName = \"Bob \" + this.lastName;\n\n//\n// GOOD\n//\nvar fullName = 'Bob ' + this.lastName;\n```\n\n<hr>\n\n- **RULE**: Strings longer than 80 characters should be written across multiple lines using string concatenation.\n\n> If overused, long strings with concatenation could impact performance. [jsPerf](http://jsperf.com/ya-string-concat) & [Discussion](https://github.com/airbnb/javascript/issues/40)\n\n``` js\n//\n// BAD\n//\nvar errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';\n\n//\n// BAD\n//\nvar errorMessage = 'This is a super long error that \\\nwas thrown because of Batman. \\\nWhen you stop to think about \\\nhow Batman had anything to do \\\nwith this, you would get nowhere \\\nfast.';\n\n//\n// GOOD\n//\nvar errorMessage = 'This is a super long error that ' +\n  'was thrown because of Batman.' +\n  'When you stop to think about ' +\n  'how Batman had anything to do ' +\n  'with this, you would get nowhere ' +\n  'fast.';\n\n//\n// GOOD\n//\nvar errorMessage = [\n  'This is a super long error that ',\n  'was thrown because of Batman.',\n  'When you stop to think about',\n  'how Batman had anything to do',\n  'with this, you would get nowhere'\n  'fast.'\n].join(' ');\n```\n\n<hr>\n\n- **RULE**: When programatically building up a string, use Array#join instead of string concatenation. Mostly for IE: [jsPerf](http://jsperf.com/string-vs-array-concat/2).\n\n``` js\nvar items,\n    messages,\n    length,\n    i;\n\nmessages = [{\n  state: 'success',\n  message: 'This one worked.'\n}, {\n  state: 'success',\n  message: 'This one worked as well.'\n}, {\n  state: 'error',\n  message: 'This one did not work.'\n}];\n\nlength = messages.length;\n\n//\n// BAD\n//\nfunction inbox(messages) {\n  items = '<ul>';\n\n  for (i = 0; i < length; i++) {\n    items += '<li>' + messages[i].message + '</li>';\n  }\n\n  return items + '</ul>';\n}\n\n//\n// GOOD\n//\nfunction inbox(messages) {\n  items = [];\n\n  for (i = 0; i < length; i++) {\n    items[i] = messages[i].message;\n  }\n\n  return '<ul><li>' + items.join('</li><li>') + '</li></ul>';\n}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Code Comments\n\n- **RULE**: You **should not** use JSDoc.\n- **RULE**: Block comments **should only** be used in file headers.\n- **RULE**: You **should not** use single-line block comments\n- **RULE**: Put an emptyline before a comment.\n\n> Having appropriate space in your code comments makes writing\n> complex code easier to read. It's the \"almost literate coding\"\n> approach.\n\n- **REMARK**: JSDoc should be considered **deprecated.** When time is available to improve the `docco`-style comments we have historically used we will replace it all together.\n\n### GOOD\n``` js\n/*\n * a-js-file.js: This is some file\n *\n * (C) 2013 Whomever\n * MIT LICENSE\n *\n */\n```\n\n``` js\n//\n// ### function myFunction (a, b, c)\n// #### @a {string} A variable\n// #### @b {boolean} Another variable\n// #### @c {object|Array} An object or an array\n//\n// This is the description to my function.\n//\n```\n\n``` js\n//\n// Adding additional padding in your code comments\n//\nvar a = 0;\n\n//\n// Along with additional whitespace\n//\nif (!a) {\n  console.log('Makes your code easier to read.');\n  console.log('What are you running out of bytes?');\n}\n```\n\n### OK\n\n``` js\n// One line comments\nvar a = 0;\n// and no whitespace\nif (!a) {\n  console.log('make your code harder to read');\n  console.log('seriously.');\n}\n```\n\n``` js\n/*\n * I'm using block comments anywhere but the file header.\n */\n```\n\n<hr>\n\n- **RULE**: Use `// FIXME:` to annotate problems.\n- **RULE**: Use `// TODO:` to annotate solutions to problems.\n- **RULE**: Use `// REMARK:` to annotate possible annotations or open implementation questions (which are not obvious problems).\n- **RULE**: Sign these comments with your Github username.\n\n### GOOD\n\n``` js\nfunction Calculator() {\n\n  // FIXME (index zero): shouldn't use a global here\n  total = 0;\n\n  return this;\n}\n```\n\n``` js\nfunction Calculator() {\n\n  // TODO (indexzero): total should be configurable by an options param\n  this.total = 0;\n\n  return this;\n}\n```\n\n### BAD\n\n``` js\nfunction Calculator() {\n\n  // shouldn't use a global here\n  total = 0;\n\n  return this;\n}\n```\n\n``` js\nfunction Calculator() {\n\n  // TODO: total should be configurable by an options param\n  this.total = 0;\n\n  return this;\n}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Constructors\n\n- **RULE**: Assign methods to the prototype object. You **must never** overwrite the prototype with a new object completely.\n\n> Overwriting the prototype makes inheritance impossible: by resetting the prototype you'll overwrite the base!\n\n``` js\nfunction Jedi() {\n  console.log('new jedi');\n}\n\n//\n// BAD\n//\nJedi.prototype = {\n  fight: function fight() {\n    console.log('fighting');\n  },\n\n  block: function block() {\n    console.log('blocking');\n  }\n};\n\n//\n// GOOD\n//\nJedi.prototype.fight = function fight() {\n  console.log('fighting');\n};\n\nJedi.prototype.block = function block() {\n  console.log('blocking');\n};\n```\n\n<hr>\n\n- **RULE**: Methods can return `this` to help with method chaining.\n\n``` js\n//\n// OK\n//\nJedi.prototype.jump = function() {\n  this.jumping = true;\n  return true;\n};\n\nJedi.prototype.setHeight = function(height) {\n  this.height = height;\n};\n\nvar luke = new Jedi();\nluke.jump(); // => true\nluke.setHeight(20) // => undefined\n\n//\n// GOOD\n//\nJedi.prototype.jump = function() {\n  this.jumping = true;\n  return this;\n};\n\nJedi.prototype.setHeight = function(height) {\n  this.height = height;\n  return this;\n};\n\nvar luke = new Jedi();\n\nluke.jump()\n  .setHeight(20);\n```\n\n<hr>\n\n- **RULE**: It's okay to write a custom toString() method, just make sure it works successfully and causes no side effects.\n\n``` js\nfunction Jedi(options) {\n  options || (options = {});\n  this.name = options.name || 'no name';\n}\n\nJedi.prototype.getName = function getName() {\n  return this.name;\n};\n\nJedi.prototype.toString = function toString() {\n  return 'Jedi - ' + this.getName();\n};\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Control-flow\n\n- **RULE**: Control-flow statements, such as `if`, `while` and `for` **must** have a space between the keyword and the left parenthesis.\n\n> They aren't functions, and thus better distinguished like this.\n\n``` js\n//\n// GOOD\n//\nif (a) {\n  return true;\n}\n```\n\n``` js\n//\n// BAD\n//\nif(a) {\n  return true;\n}\n```\n\n<hr>\n\n- **RULE**: Eager returns **must be** preferred over `if else` blocks.\n\n> Eager returns simplifies most control-flow, especially more complex and high-level control-flow.\n\n``` js\n//\n// BAD\n//\nif (foo) {\n  callback(null, 'foo');\n}\nelse {\n  callback(null, 'bar');\n}\n```\n\n``` js\n//\n// GOOD\n//\nif (foo) {\n  return callback(null, 'foo');\n}\n\ncallback(null, 'bar');\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Functions\n\n- **RULE**: Anonymous functions **must** have a space between the `function` keyword and the left parenthesis.\n\n> To emphasise the lack of identifier and differentiate them with named functions.\n\n``` js\n//\n// GOOD\n//\nfunction (a, b) {}\n```\n\n``` js\n//\n// BAD\n//\nfunction(a, b) {}\n```\n\n<hr>\n\n- **RULE**: Named functions **must not** have a space between the function name and the left parenthesis.\n- **RULE**: Function calls **must not** have a space between the function name and the left parenthesis.\n\n``` js\n//\n// GOOD\n//\nfunction add(a, b) {}\n```\n\n``` js\n//\n// BAD\n//\nfunction add (a, b) {}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Conditionals\n\n- **RULE**: Multi-line conditional statements **must** be properly indented.\n- **RULE**: Newlines in multi-line conditional statements **must** be be followed by a boolean operator or `(`.\n- **RULE**: Conditional **should not** contain complex logic.\n\n``` js\n//\n// GOOD\n//\nif (something === 'foo' && (somethingElse === 'bar'\n    && ohYeahThisToo === 'bazz')) {\n  return false;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (something === 'foo' && (somethingElse === 'bar' &&\nohYeahThisToo === 'bazz')) {\n  return false;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (something === 'foo' && (somethingElse === 'bar' &&\n    ohYeahThisToo === 'bazz') {\n  return false;\n}\n```\n\n``` js\n//\n// OK\n//\nif (list.filter(function (i) { return i.ok }).length > 5) {\n  return false;\n}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Type Casting & Coercion\n\n- **RULE**: Perform type coercion at the beginning of the statement.\n\n``` js\n//  => this.reviewScore = 9;\n\n//\n// BAD\n//\nvar totalScore = this.reviewScore + '';\n\n//\n// GOOD\n//\nvar totalScore = '' + this.reviewScore;\n\n//\n// BAD\n//\nvar totalScore = '' + this.reviewScore + ' total score';\n\n//\n// GOOD\n//\nvar totalScore = this.reviewScore + ' total score';\n```\n\n<hr>\n\n- **RULE**: Use `parseInt` for Numbers and always with a radix for type casting.\n\n> If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need\n> to use Bitshift for [performance reasons](http://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you're doing.\n\n**Numbers**\n\n``` js\nvar inputValue = '4';\n\n//\n// OK\n//\nvar val = +inputValue;\n\n//\n// BAD\n//\nvar val = new Number(inputValue);\n\n//\n// BAD\n//\nvar val = inputValue >> 0;\n\n//\n// BAD\n//\nvar val = parseInt(inputValue);\n\n//\n// GOOD\n//\nvar val = Number(inputValue);\n\n//\n// GOOD\n//\nvar val = parseInt(inputValue, 10);\n\n//\n// GOOD\n//\n\n//\n// parseInt was the reason my code was slow.\n// Bitshifting the String to coerce it to a\n// Number made it a lot faster.\n//\nvar val = inputValue >> 0;\n```\n\n**Booleans**\n\n``` js\nvar age = 0;\n\n//\n// BAD\n//\nvar hasAge = new Boolean(age);\n\n//\n// GOOD\n//\nvar hasAge = Boolean(age);\n\n//\n// GOOD\n//\nvar hasAge = !!age;\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Ternary operators\n\n- **RULE**: Ternary operators are OK, but **must never be combined**.\n\n> More than one and it's spaghetti.\n\n``` js\n//\n// GOOD\n//\nvar i = 2,\n    x = i > 5 ? i : 0;\n```\n\n``` js\n//\n// BAD\n//\nvar i = 2,\n    j = 3,\n    x = i > 5 ? j > 4 ? j : i : 0;\n```\n\n<hr>\n\n- **RULE**: Multi-line Ternary operators are OK, but **must be single line statements.**.\n\n``` js\n  //\n  // GOOD\n  //\n  return foo\n    ? foo + 1\n    : bar;\n```\n\n``` js\n  //\n  // GOOD\n  //\n  return foo ? foo + 1 : bar;\n```\n\n``` js\n  //\n  // GOOD\n  //\n  return foo\n    ? function () { return foo + 1 }\n    : bar;\n```\n\n``` js\n  //\n  // GOOD\n  //\n  return err\n    ? callback(err)\n    : callback();\n```\n\n``` js\n  //\n  // BAD\n  //\n  return foo ?\n    foo + 1 :\n    bar;\n```\n\n``` js\n  //\n  // BAD\n  //\n  return foo\n    ? foo + 1 :\n    bar;\n```\n\n``` js\n  //\n  // BAD\n  //\n  return foo\n    ? function (wtf) {\n      return foo + 1; // No multi-line return values!\n    }\n    : bar;\n```\n\n<hr>\n\n- **RULE**: Ternary operators combined with `return` **should be** preferred over `if (err) { return }` blocks.\n\n``` js\n  //\n  // OK\n  //\n  if (err) {\n    return callback(err);\n  }\n\n  callback();\n```\n\n``` js\n  //\n  // GOOD\n  //\n  return err\n    ? callback(err)\n    : callback();\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Errors\n\n- **RULE**: You **must always** throw or return an error. [A string is not an Error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/).\n\n> If you want more descriptive Errors, use [errs](https://github.com/flatiron/errs).\n\n``` js\n//\n// GOOD\n//\nthrow new Error('I have a call-stack and other good things.');\n```\n\n``` js\n//\n// GOOD\n//\ncallback(new Error('I have a call-stack and other good things.'));\n```\n\n``` js\n//\n// BAD\n//\nthrow 'I have no call-stack no interesting properties.';\n```\n\n``` js\n//\n// BAD\n//\ncallback('I have no call-stack no interesting properties.');\n```\n\n``` js\n//\n// BAD\n//\nthrow { message: 'I have no call-stack no interesting properties.' };\n```\n\n``` js\n//\n// BAD\n//\ncallback({\n  message: 'I have no call-stack no interesting properties.'\n});\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Exports\n\n- **RULE**: If you are exporting something, it **should** be exported on the same line as the declaration.\n\n> Makes it easier to understand what the exports are immediately in the same context.\n\n``` js\n//\n// GOOD\n//\nvar Foo = exports.Foo = function () {\n  //...\n};\n```\n\n``` js\n//\n// BAD\n//\nvar Foo = function () {\n  //...\n};\n\n//\n// Lots of other code changing my mental context\n// by the time I see Foo again I forgot what it was.\n//\n\nexports.Foo = Foo;\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Async Programming\n\n- **RULE**: You **must not** use promises.\n- **RULE**: You **must** use [async](https://github.com/caolan/async).\n\n> Just use async. If you love promises then sorry; this decision\n> is final and _not up for debate_ **_â€¦ ever._**\n\n``` js\n//\n// GOOD\n//\nvar async = require('async');\n```\n\n``` js\n//\n// BAD\n//\nvar Q = require('q');\n```\n\n<hr>\n\n- **RULE**: A given function **must not** have more than **three** callback functions.\n\n> Rule of three. What? It works in fairy tales.\n\n> INSERT CODE EXAMPLES HERE\n\n- **RULE**: Named functions **should** be preferred over anonymous inline functions.\n\n**[[â¬†]](#table-of-contents)**\n\n### Attribution (with modifications and additions)\n\n* https://github.com/cloudhead/styleguide/blob/master/JavaScript.md\n* https://github.com/airbnb/javascript\n\n> The following files include software modified from <br>\n> `eslint-config-godaddy` with attribution under MIT <br>\n> © GoDaddy Operating Company 2016 <br>\n> ```\n> index.js\n> bin/eslint-autofix.js\n> ```\n> Modifications © Charlie Robbins 2017\n","readmeFilename":"README.md"}