{"id":13403117,"url":"https://github.com/indexzero/populist-style","last_synced_at":"2025-12-17T02:46:30.403Z","repository":{"id":23206323,"uuid":"26563146","full_name":"indexzero/populist-style","owner":"indexzero","description":"A (one day) auto-updating style at the mercy of the people, and only the people.","archived":false,"fork":false,"pushed_at":"2021-05-09T21:56:04.000Z","size":100,"stargazers_count":21,"open_issues_count":10,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-29T12:31:08.033Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/indexzero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-13T00:36:04.000Z","updated_at":"2025-03-04T10:47:32.000Z","dependencies_parsed_at":"2022-08-05T21:00:24.981Z","dependency_job_id":null,"html_url":"https://github.com/indexzero/populist-style","commit_stats":null,"previous_names":["indexzero/styleguide","indexzero/common-style"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/indexzero/populist-style","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indexzero%2Fpopulist-style","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indexzero%2Fpopulist-style/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indexzero%2Fpopulist-style/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indexzero%2Fpopulist-style/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/indexzero","download_url":"https://codeload.github.com/indexzero/populist-style/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indexzero%2Fpopulist-style/sbom","scorecard":{"id":487262,"data":{"date":"2025-08-11","repo":{"name":"github.com/indexzero/populist-style","commit":"888138a3b7ef4e0d80eabc057d36c0d248a35f40"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"21 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T18:08:14.957Z","repository_id":23206323,"created_at":"2025-08-19T18:08:14.957Z","updated_at":"2025-08-19T18:08:14.957Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27775739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-17T02:00:08.291Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T19:01:25.649Z","updated_at":"2025-12-17T02:46:30.385Z","avatar_url":"https://github.com/indexzero.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"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\u003e If you have comments on this or **disagree about rules** then\n\u003e 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 \u0026 Coercion](#type-casting--coercion)\n* [Ternary Operators](#ternary-operators)\n* [Errors](#errors)\n* [Exports](#exports)\n* [Async](#async-programming)\n\n\u003e [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\u003chr\u003e\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\u003e Vertical screen space is precious, and ease of scanning code\n\u003e 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\u003chr\u003e\n\n- **RULE**: Closing Braces **must always** be on a line of their own unless they also start on that line.\n\n\u003e This makes it easy to see the end of a function or statement\n\n``` js\n//\n// GOOD\n//\nreturn callback \u0026\u0026 callback({ foo: bar });\n```\n\n``` js\n//\n// GOOD\n//\nreturn callback \u0026\u0026 callback({\n  foo: bar\n});\n```\n\n``` js\n//\n// BAD\n//\nreturn callback \u0026\u0026 callback({\n  foo: bar });\n```\n\n``` js\n//\n// BAD\n//\nreturn callback \u0026\u0026 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\u003chr\u003e\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\u003chr\u003e\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\u003chr\u003e\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\u003chr\u003e\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\u003chr\u003e\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\u003chr\u003e\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\u003e Variable declarations are moved up to the top of the function\n\u003e 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 \u003c 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\u003chr\u003e\n\n- **RULE**: Variables **must** always align when they are declared\n\n\u003e 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\u003chr\u003e\n\n- **RULE**: Declare unassigned variables last.\n\n\u003e 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\u003chr\u003e\n\n- **RULE**: Variables **should** always be declared in decreasing length.\n\n\u003e 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\u003chr\u003e\n\n- **RULE**: Variable assignments **must** come before declarations.\n- **RULE**: Variable assignments **should** align **when convenient** depending on additional length.\n\n\u003e 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\u003chr\u003e\n\n- **RULE**: Multi-line object literals **must be** assigned outside of multi-line variable declaration blocks.\n\n\u003e 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\u003chr\u003e\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 \u003c 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 \u003c 10;\n}).filter(Boolean);\n```\n\n``` js\n//\n// BAD\n//\nvar memo = list.filter(function (i) {\n  return i \u003c 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 \u003c 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 \u003c 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\u003chr\u003e\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\u003chr\u003e\n\n- **RULE**: Multi-line assignment statements **inside an object literal** are **encouraged.**\n\n\u003e 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\u003chr\u003e\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\u003chr\u003e\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\u003chr\u003e\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 \u003c 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\u003chr\u003e\n\n- **RULE**: Strings longer than 80 characters should be written across multiple lines using string concatenation.\n\n\u003e If overused, long strings with concatenation could impact performance. [jsPerf](http://jsperf.com/ya-string-concat) \u0026 [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\u003chr\u003e\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 = '\u003cul\u003e';\n\n  for (i = 0; i \u003c length; i++) {\n    items += '\u003cli\u003e' + messages[i].message + '\u003c/li\u003e';\n  }\n\n  return items + '\u003c/ul\u003e';\n}\n\n//\n// GOOD\n//\nfunction inbox(messages) {\n  items = [];\n\n  for (i = 0; i \u003c length; i++) {\n    items[i] = messages[i].message;\n  }\n\n  return '\u003cul\u003e\u003cli\u003e' + items.join('\u003c/li\u003e\u003cli\u003e') + '\u003c/li\u003e\u003c/ul\u003e';\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\u003e Having appropriate space in your code comments makes writing\n\u003e complex code easier to read. It's the \"almost literate coding\"\n\u003e 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\u003chr\u003e\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\u003e 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\u003chr\u003e\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(); // =\u003e true\nluke.setHeight(20) // =\u003e 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\u003chr\u003e\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\u003e 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\u003chr\u003e\n\n- **RULE**: Eager returns **must be** preferred over `if else` blocks.\n\n\u003e 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\u003e 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\u003chr\u003e\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' \u0026\u0026 (somethingElse === 'bar'\n    \u0026\u0026 ohYeahThisToo === 'bazz')) {\n  return false;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (something === 'foo' \u0026\u0026 (somethingElse === 'bar' \u0026\u0026\nohYeahThisToo === 'bazz')) {\n  return false;\n}\n```\n\n``` js\n//\n// BAD\n//\nif (something === 'foo' \u0026\u0026 (somethingElse === 'bar' \u0026\u0026\n    ohYeahThisToo === 'bazz') {\n  return false;\n}\n```\n\n``` js\n//\n// OK\n//\nif (list.filter(function (i) { return i.ok }).length \u003e 5) {\n  return false;\n}\n```\n\n**[[â¬†]](#table-of-contents)**\n\n## Type Casting \u0026 Coercion\n\n- **RULE**: Perform type coercion at the beginning of the statement.\n\n``` js\n//  =\u003e 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\u003chr\u003e\n\n- **RULE**: Use `parseInt` for Numbers and always with a radix for type casting.\n\n\u003e If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need\n\u003e 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 \u003e\u003e 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 \u003e\u003e 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\u003e More than one and it's spaghetti.\n\n``` js\n//\n// GOOD\n//\nvar i = 2,\n    x = i \u003e 5 ? i : 0;\n```\n\n``` js\n//\n// BAD\n//\nvar i = 2,\n    j = 3,\n    x = i \u003e 5 ? j \u003e 4 ? j : i : 0;\n```\n\n\u003chr\u003e\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\u003chr\u003e\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\u003e 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\u003e 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\u003e Just use async. If you love promises then sorry; this decision\n\u003e 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\u003chr\u003e\n\n- **RULE**: A given function **must not** have more than **three** callback functions.\n\n\u003e Rule of three. What? It works in fairy tales.\n\n\u003e 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\u003e The following files include software modified from \u003cbr\u003e\n\u003e `eslint-config-godaddy` with attribution under MIT \u003cbr\u003e\n\u003e © GoDaddy Operating Company 2016 \u003cbr\u003e\n\u003e ```\n\u003e index.js\n\u003e bin/eslint-autofix.js\n\u003e ```\n\u003e Modifications © Charlie Robbins 2017\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findexzero%2Fpopulist-style","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Findexzero%2Fpopulist-style","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findexzero%2Fpopulist-style/lists"}