From 33a9e3336ca29893249f6a55873cdd0c9c15efa4 Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 23 Oct 2014 16:22:16 -0400 Subject: [PATCH 01/15] (always-use-braces) default to using braces, but, allow for not in some instances without encouraging it --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16b08d5..ebc8164 100644 --- a/README.md +++ b/README.md @@ -529,7 +529,7 @@ return false; } - // bad + // good function () { return false; } // good From 9a8a67f0795eae157f1c6b1caf104a343a435e49 Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 23 Oct 2014 16:28:04 -0400 Subject: [PATCH 02/15] (always-use-braces) default to using braces, but, allow for not in some instances without encouraging it --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ebc8164..934a503 100644 --- a/README.md +++ b/README.md @@ -521,9 +521,6 @@ if (test) return false; - // good (only for very simple statements and early function return) - if (test) return false; - // good if (test) { return false; @@ -536,6 +533,9 @@ function () { return false; } + + // acceptable (only for very simple statements and early function return) + if (test) return false; ``` **[[⬆]](#TOC)** From cde9a9665c8ce786335835ff36b3c4a2701cfd0c Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Mon, 1 Dec 2014 10:06:39 -0500 Subject: [PATCH 03/15] (master) added EsFormatter settings --- linters/EsFormatter.sublime-settings | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 linters/EsFormatter.sublime-settings diff --git a/linters/EsFormatter.sublime-settings b/linters/EsFormatter.sublime-settings new file mode 100644 index 0000000..10d7b52 --- /dev/null +++ b/linters/EsFormatter.sublime-settings @@ -0,0 +1,19 @@ +{ + // Format the file when saved + "format_on_save": true, + + // EsFormatter specific options + // default are specified here https://github.com/millermedeiros/esformatter/blob/master/lib/preset/default.json + "format_options" : { + + "indent": { + "value": "\t", + }, + "whiteSpace": { + "after": { + "FunctionReservedWord": 1, + "FunctionName": 0, + } + } + } +} \ No newline at end of file From 91be8c28dcc0ee19706dfcda8707cce787d83ebf Mon Sep 17 00:00:00 2001 From: benjaminneildavis Date: Tue, 9 Dec 2014 17:50:39 -0500 Subject: [PATCH 04/15] Adding editorconfig file and my personal webstorm settings file (just the file formatting part of it). --- .editorconfig | 18 ++++++++++++++++++ README.md | 17 +++++++++++++++++ linters/webstorm-settings.jar | Bin 0 -> 1264 bytes 3 files changed, 35 insertions(+) create mode 100644 .editorconfig create mode 100644 linters/webstorm-settings.jar diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8a6f796 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[package.json] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.js] +curly_bracket_next_line = false diff --git a/README.md b/README.md index a19c88b..d82c5fe 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ 1. [ES5 Compatibility](#es5) 1. [Testing](#testing) 1. [Performance](#performance) + 1. [Editorconfig Setup / Use](#editorconfig) 1. [Resources](#resources) 1. [In the Wild](#in-the-wild) 1. [The JavaScript Style Guide Guide](#guide-guide) @@ -1195,6 +1196,22 @@ - Loading... **[[⬆]](#TOC)** + +## Editorconfig Setup / Use + - Usually for a project with more than one developer involved, it is essentially important for the project to define + and maintain a consistent coding style. Most code editors and IDEs, such as Vim, Emacs, Code::Blocks, provide settings + related to coding styles, such as the width of tab, the size of indentation, end of line, etc. However, it is hard to + provide the same settings for different Editors and IDEs: we have to maintain many config files for different editors + and IDEs, such as .vimrc for Vim, .emacs for Emacs. In order to solve this, EditorConfig was born. By defining coding + style in files named .editorconfig, the EditorConfig plugins for different editors and IDEs will automatically adjust + your coding style. + - To use EditorConfig, you have to download the corresponding [EditorConfig plugins](http://editorconfig.org/#download) for your Editor or IDE. + Follow the installation instructions to install them. + - The "base" .editorconfig file goes in the root directory. You can have other config files in specific folders if wanted. + The only difference would be at the top of the file to remove root = true from any file that isn't the root. + + + **[[⬆]](#TOC)** ## Resources diff --git a/linters/webstorm-settings.jar b/linters/webstorm-settings.jar new file mode 100644 index 0000000000000000000000000000000000000000..87655234d3c8146886cc0a808ebe8ed944049cd9 GIT binary patch literal 1264 zcmWIWW@Zs#-~hr|k*%%_NI;H(g(1J7Br`v+SU)*GB~`Duq%sFcCTFDPrWWf}(+S8gXOZj(W{U zpZsQ7RLYCF#XM+;-fpr#C;IxDEUUPfh?BcsMHsb2uFy1h?pPk-jzXNt<1?)9Xbe`{cvnt4`2{}nH>mD}><-@SR*o4W9=pZe`J zb10J?3bL{L$dgrdVI)SZXLgvE0^Y)phjX&QfM2qGn*x#CVx$oPe3BMomOn^r@mbA>CFEUv5A*IxcMo6T_1bOcHbxI4TFI8h=Y*?I{<-KP+^j^Gd{o~s7y~a8& zqP=4Jo08i4)0+=!mEJ#iyhhShD4b>0PXQxNvy}ZNTmM%{rGLErf*It9o+a_YUO+2? zfEba!&>bNQl=aLjNzKX0^iuG2adlL1&&f|p%uxtVEh)*&OD_)aW@Hj!Kx9JXWDClK zsDN;m1ewRhfIG1x%zFW3q9lEULqLfiIgmk#9{~h`L64*nEh`{<2oxH~;RK2j1USru i7D32v#}<$Xtscw-gOwGSI2agMfiN8C-e#Z%1_l6jzoLQw literal 0 HcmV?d00001 From ba9eb12883f52a00d8863957ce2a3fbc9dcd2d7b Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 2 Apr 2015 12:02:06 -0400 Subject: [PATCH 05/15] (master) updates esformatter settings to be more correct --- linters/EsFormatter.sublime-settings | 293 ++++++++++++++++++++++++++- 1 file changed, 292 insertions(+), 1 deletion(-) diff --git a/linters/EsFormatter.sublime-settings b/linters/EsFormatter.sublime-settings index 10d7b52..d65205e 100644 --- a/linters/EsFormatter.sublime-settings +++ b/linters/EsFormatter.sublime-settings @@ -2,18 +2,309 @@ // Format the file when saved "format_on_save": true, + // Path to the node executable, by default it tries to resolve the executable + // for the command 'node' or 'nodejs'. Change this value to specify your own path + "nodejs_path": null, + // EsFormatter specific options // default are specified here https://github.com/millermedeiros/esformatter/blob/master/lib/preset/default.json "format_options" : { + // You can change the preset for any other available on ESFormatter + // Ref: https://github.com/millermedeiros/esformatter/tree/master/lib/preset + // e.g.: "preset": "jquery" + "preset": "default", + "indent": { - "value": "\t", + "value": " ", + "ArrayExpression": 1, + "AssignmentExpression": 1, + "BinaryExpression": 1, + "ConditionalExpression": 1, + "CallExpression": 1, + "CatchClause": 1, + "DoWhileStatement": 1, + "ForInStatement": 1, + "ForStatement": 1, + "FunctionDeclaration": 1, + "FunctionExpression": 1, + "IfStatement": 1, + "MemberExpression": 1, + "MultipleVariableDeclaration": 1, + "ObjectExpression": 1, + "ReturnStatement": 1, + "SwitchCase": 1, + "SwitchStatement": 1, + "TopLevelFunctionBlock": 1, + "TryStatement": 1, + "WhileStatement": 1 + }, + "lineBreak": { + "value": "\n", + "before": { + "AssignmentExpression": ">=1", + "AssignmentOperator": 0, + "BlockStatement": 0, + "CallExpression": -1, + "ConditionalExpression": ">=1", + "CatchOpeningBrace": 0, + "CatchClosingBrace": ">=1", + "CatchKeyword": 0, + "DeleteOperator": ">=1", + "DoWhileStatement": ">=1", + "DoWhileStatementOpeningBrace": 0, + "DoWhileStatementClosingBrace": ">=1", + "EndOfFile": 2, + "EmptyStatement": -1, + "FinallyOpeningBrace": 0, + "FinallyClosingBrace": ">=1", + "ForInStatement": ">=1", + "ForInStatementExpressionOpening": 0, + "ForInStatementExpressionClosing": 0, + "ForInStatementOpeningBrace": 0, + "ForInStatementClosingBrace": ">=1", + "ForStatement": ">=1", + "ForStatementExpressionOpening": 0, + "ForStatementExpressionClosing": "<2", + "ForStatementOpeningBrace": 0, + "ForStatementClosingBrace": ">=1", + "FunctionExpression": 0, + "FunctionExpressionOpeningBrace": 0, + "FunctionExpressionClosingBrace": 1, + "FunctionDeclaration": ">=1", + "FunctionDeclarationOpeningBrace": 0, + "FunctionDeclarationClosingBrace": ">=1", + "IfStatement": ">=1", + "IfStatementOpeningBrace": 0, + "IfStatementClosingBrace": ">=1", + "ElseIfStatement": 0, + "ElseIfStatementOpeningBrace": 0, + "ElseIfStatementClosingBrace": ">=1", + "ElseStatement": 0, + "ElseStatementOpeningBrace": 0, + "ElseStatementClosingBrace": ">=1", + "LogicalExpression": -1, + "ObjectExpressionClosingBrace": 1, + "Property": ">=1", + "ReturnStatement": -1, + "SwitchOpeningBrace": 0, + "SwitchClosingBrace": ">=1", + "ThisExpression": -1, + "ThrowStatement": ">=1", + "TryOpeningBrace": 0, + "TryClosingBrace": ">=1", + "VariableName": ">=1", + "VariableValue": 0, + "VariableDeclaration": ">=1", + "VariableDeclarationWithoutInit": ">=1", + "WhileStatement": ">=1", + "WhileStatementOpeningBrace": 0, + "WhileStatementClosingBrace": ">=1" + }, + "after": { + "AssignmentExpression": ">=1", + "AssignmentOperator": 0, + "BlockStatement": 0, + "CallExpression": -1, + "CatchOpeningBrace": ">=1", + "CatchClosingBrace": ">=0", + "CatchKeyword": 0, + "ConditionalExpression": ">=1", + "DeleteOperator": ">=1", + "DoWhileStatement": ">=1", + "DoWhileStatementOpeningBrace": ">=1", + "DoWhileStatementClosingBrace": 0, + "EmptyStatement": -1, + "FinallyOpeningBrace": ">=1", + "FinallyClosingBrace": ">=1", + "ForInStatement": ">=1", + "ForInStatementExpressionOpening": "<2", + "ForInStatementExpressionClosing": -1, + "ForInStatementOpeningBrace": ">=1", + "ForInStatementClosingBrace": ">=1", + "ForStatement": ">=1", + "ForStatementExpressionOpening": "<2", + "ForStatementExpressionClosing": -1, + "ForStatementOpeningBrace": ">=1", + "ForStatementClosingBrace": ">=1", + "FunctionExpression": ">=1", + "FunctionExpressionOpeningBrace": 1, + "FunctionExpressionClosingBrace": -1, + "FunctionDeclaration": ">=1", + "FunctionDeclarationOpeningBrace": 1, + "FunctionDeclarationClosingBrace": ">=1", + "IfStatement": 1, + "IfStatementOpeningBrace": 1, + "IfStatementClosingBrace": 2, + "ElseIfStatement": ">=1", + "ElseIfStatementOpeningBrace": 1, + "ElseIfStatementClosingBrace": 2, + "ElseStatement": ">=1", + "ElseStatementOpeningBrace": 1, + "ElseStatementClosingBrace": 2, + "LogicalExpression": -1, + "ObjectExpressionOpeningBrace": ">=1", + "Property": 0, + "ReturnStatement": -1, + "SwitchOpeningBrace": ">=1", + "SwitchClosingBrace": ">=1", + "ThisExpression": 0, + "ThrowStatement": ">=1", + "TryOpeningBrace": ">=1", + "TryClosingBrace": 0, + "VariableDeclaration": ">=1", + "WhileStatement": ">=1", + "WhileStatementOpeningBrace": ">=1", + "WhileStatementClosingBrace": ">=1" + } }, "whiteSpace": { + "value": " ", + "removeTrailing": 1, + "before": { + "ArrayExpressionOpening": 0, + "ArrayExpressionClosing": 0, + "ArrayExpressionComma": 0, + "ArgumentComma": 0, + "ArgumentList": 0, + "ArgumentListArrayExpression": 0, + "ArgumentListFunctionExpression": 0, + "ArgumentListObjectExpression": 0, + "AssignmentOperator": 1, + "BinaryExpression": 0, + "BinaryExpressionOperator": 1, + "BlockComment": 0, + "CallExpression": -1, + "CatchParameterList": 0, + "CatchOpeningBrace": 1, + "CatchClosingBrace": 1, + "CatchKeyword": 1, + "CommaOperator": 0, + "ConditionalExpressionConsequent": 1, + "ConditionalExpressionAlternate": 1, + "DoWhileStatementOpeningBrace": 1, + "DoWhileStatementClosingBrace": 1, + "DoWhileStatementConditional": 1, + "EmptyStatement": 0, + "ExpressionClosingParentheses": 0, + "FinallyOpeningBrace": 1, + "FinallyClosingBrace": 1, + "ForInStatement": 1, + "ForInStatementExpressionOpening": 1, + "ForInStatementExpressionClosing": 0, + "ForInStatementOpeningBrace": 1, + "ForInStatementClosingBrace": 1, + "ForStatement": 1, + "ForStatementExpressionOpening": 1, + "ForStatementExpressionClosing": 0, + "ForStatementOpeningBrace": 1, + "ForStatementClosingBrace": 1, + "ForStatementSemicolon": 0, + "FunctionDeclarationOpeningBrace": 1, + "FunctionDeclarationClosingBrace": 1, + "FunctionExpressionOpeningBrace": 1, + "FunctionExpressionClosingBrace": 1, + "IfStatementConditionalOpening": 1, + "IfStatementConditionalClosing": 0, + "IfStatementOpeningBrace": 1, + "IfStatementClosingBrace": 0, + "ElseStatementOpeningBrace": 1, + "ElseStatementClosingBrace": 1, + "ElseIfStatementOpeningBrace": 1, + "ElseIfStatementClosingBrace": 1, + "MemberExpressionClosing": 0, + "LineComment": 0, + "LogicalExpressionOperator": 1, + "Property": 1, + "PropertyValue": 1, + "ParameterComma": 0, + "ParameterList": 0, + "SwitchDiscriminantOpening": 1, + "SwitchDiscriminantClosing": 0, + "ThrowKeyword": 1, + "TryOpeningBrace": 1, + "TryClosingBrace": 1, + "UnaryExpressionOperator": 0, + "VariableName": 1, + "VariableValue": 1, + "WhileStatementConditionalOpening": 1, + "WhileStatementConditionalClosing": 0, + "WhileStatementOpeningBrace": 1, + "WhileStatementClosingBrace": 1 + }, "after": { + "ArrayExpressionOpening": 0, + "ArrayExpressionClosing": 0, + "ArrayExpressionComma": 1, + "ArgumentComma": 1, + "ArgumentList": 0, + "ArgumentListArrayExpression": 0, + "ArgumentListFunctionExpression": 0, + "ArgumentListObjectExpression": 0, + "AssignmentOperator": 1, + "BinaryExpression": 0, + "BinaryExpressionOperator": 1, + "BlockComment": 1, + "CallExpression": 0, + "CatchParameterList": 0, + "CatchOpeningBrace": 1, + "CatchClosingBrace": 1, + "CatchKeyword": 1, + "CommaOperator": 1, + "ConditionalExpressionConsequent": 1, + "ConditionalExpressionTest": 1, + "DoWhileStatementOpeningBrace": 1, + "DoWhileStatementClosingBrace": 1, + "DoWhileStatementBody": 1, + "EmptyStatement": 0, + "ExpressionOpeningParentheses": 0, + "FinallyOpeningBrace": 1, + "FinallyClosingBrace": 1, + "ForInStatement": 1, + "ForInStatementExpressionOpening": 0, + "ForInStatementExpressionClosing": 1, + "ForInStatementOpeningBrace": 1, + "ForInStatementClosingBrace": 1, + "ForStatement": 1, + "ForStatementExpressionOpening": 0, + "ForStatementExpressionClosing": 1, + "ForStatementClosingBrace": 1, + "ForStatementOpeningBrace": 1, + "ForStatementSemicolon": 1, "FunctionReservedWord": 1, "FunctionName": 0, + "FunctionExpressionOpeningBrace": 1, + "FunctionExpressionClosingBrace": 0, + "FunctionDeclarationOpeningBrace": 1, + "FunctionDeclarationClosingBrace": 1, + "IfStatementConditionalOpening": 0, + "IfStatementConditionalClosing": 1, + "IfStatementOpeningBrace": 1, + "IfStatementClosingBrace": 1, + "ElseStatementOpeningBrace": 1, + "ElseStatementClosingBrace": 1, + "ElseIfStatementOpeningBrace": 1, + "ElseIfStatementClosingBrace": 1, + "MemberExpressionOpening": 0, + "LogicalExpressionOperator": 1, + "ObjectExpressionClosingBrace": 0, + "PropertyName": 0, + "PropertyValue": 0, + "ParameterComma": 1, + "ParameterList": 0, + "SwitchDiscriminantOpening": 0, + "SwitchDiscriminantClosing": 1, + "ThrowKeyword": 1, + "TryOpeningBrace": 1, + "TryClosingBrace": 1, + "UnaryExpressionOperator": 0, + "VariableName": 1, + "WhileStatementConditionalOpening": 0, + "WhileStatementConditionalClosing": 1, + "WhileStatementOpeningBrace": 1, + "WhileStatementClosingBrace": 1 } } } + } \ No newline at end of file From adb5d49a2de0a4fcada29fe1d728d187b3e09186 Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 2 Apr 2015 13:17:50 -0400 Subject: [PATCH 06/15] (master) fixes copy/paste error of spaces instead of tab --- linters/EsFormatter.sublime-settings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linters/EsFormatter.sublime-settings b/linters/EsFormatter.sublime-settings index d65205e..b374ef7 100644 --- a/linters/EsFormatter.sublime-settings +++ b/linters/EsFormatter.sublime-settings @@ -16,7 +16,7 @@ "preset": "default", "indent": { - "value": " ", + "value": " ", "ArrayExpression": 1, "AssignmentExpression": 1, "BinaryExpression": 1, From 2c68e8cc3a40ed5813a1e27d70e0d791dac213f3 Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 2 Apr 2015 13:25:22 -0400 Subject: [PATCH 07/15] (master) removes settings that don't actually change the default --- linters/EsFormatter.sublime-settings | 261 +-------------------------- 1 file changed, 3 insertions(+), 258 deletions(-) diff --git a/linters/EsFormatter.sublime-settings b/linters/EsFormatter.sublime-settings index b374ef7..abfbb2d 100644 --- a/linters/EsFormatter.sublime-settings +++ b/linters/EsFormatter.sublime-settings @@ -2,307 +2,52 @@ // Format the file when saved "format_on_save": true, - // Path to the node executable, by default it tries to resolve the executable - // for the command 'node' or 'nodejs'. Change this value to specify your own path - "nodejs_path": null, - // EsFormatter specific options // default are specified here https://github.com/millermedeiros/esformatter/blob/master/lib/preset/default.json "format_options" : { - // You can change the preset for any other available on ESFormatter - // Ref: https://github.com/millermedeiros/esformatter/tree/master/lib/preset - // e.g.: "preset": "jquery" - "preset": "default", - "indent": { "value": " ", - "ArrayExpression": 1, - "AssignmentExpression": 1, "BinaryExpression": 1, "ConditionalExpression": 1, - "CallExpression": 1, - "CatchClause": 1, - "DoWhileStatement": 1, - "ForInStatement": 1, - "ForStatement": 1, - "FunctionDeclaration": 1, - "FunctionExpression": 1, - "IfStatement": 1, - "MemberExpression": 1, - "MultipleVariableDeclaration": 1, - "ObjectExpression": 1, - "ReturnStatement": 1, - "SwitchCase": 1, - "SwitchStatement": 1, - "TopLevelFunctionBlock": 1, - "TryStatement": 1, - "WhileStatement": 1 }, "lineBreak": { "value": "\n", "before": { - "AssignmentExpression": ">=1", - "AssignmentOperator": 0, - "BlockStatement": 0, - "CallExpression": -1, - "ConditionalExpression": ">=1", - "CatchOpeningBrace": 0, - "CatchClosingBrace": ">=1", - "CatchKeyword": 0, - "DeleteOperator": ">=1", - "DoWhileStatement": ">=1", - "DoWhileStatementOpeningBrace": 0, - "DoWhileStatementClosingBrace": ">=1", "EndOfFile": 2, - "EmptyStatement": -1, - "FinallyOpeningBrace": 0, - "FinallyClosingBrace": ">=1", - "ForInStatement": ">=1", - "ForInStatementExpressionOpening": 0, - "ForInStatementExpressionClosing": 0, - "ForInStatementOpeningBrace": 0, - "ForInStatementClosingBrace": ">=1", - "ForStatement": ">=1", - "ForStatementExpressionOpening": 0, - "ForStatementExpressionClosing": "<2", - "ForStatementOpeningBrace": 0, - "ForStatementClosingBrace": ">=1", "FunctionExpression": 0, - "FunctionExpressionOpeningBrace": 0, "FunctionExpressionClosingBrace": 1, - "FunctionDeclaration": ">=1", - "FunctionDeclarationOpeningBrace": 0, - "FunctionDeclarationClosingBrace": ">=1", - "IfStatement": ">=1", - "IfStatementOpeningBrace": 0, - "IfStatementClosingBrace": ">=1", - "ElseIfStatement": 0, - "ElseIfStatementOpeningBrace": 0, - "ElseIfStatementClosingBrace": ">=1", - "ElseStatement": 0, - "ElseStatementOpeningBrace": 0, - "ElseStatementClosingBrace": ">=1", - "LogicalExpression": -1, - "ObjectExpressionClosingBrace": 1, - "Property": ">=1", - "ReturnStatement": -1, - "SwitchOpeningBrace": 0, - "SwitchClosingBrace": ">=1", - "ThisExpression": -1, - "ThrowStatement": ">=1", - "TryOpeningBrace": 0, - "TryClosingBrace": ">=1", - "VariableName": ">=1", - "VariableValue": 0, - "VariableDeclaration": ">=1", - "VariableDeclarationWithoutInit": ">=1", - "WhileStatement": ">=1", - "WhileStatementOpeningBrace": 0, - "WhileStatementClosingBrace": ">=1" + "ObjectExpressionClosingBrace": 1 }, "after": { - "AssignmentExpression": ">=1", - "AssignmentOperator": 0, - "BlockStatement": 0, - "CallExpression": -1, - "CatchOpeningBrace": ">=1", - "CatchClosingBrace": ">=0", - "CatchKeyword": 0, - "ConditionalExpression": ">=1", - "DeleteOperator": ">=1", - "DoWhileStatement": ">=1", - "DoWhileStatementOpeningBrace": ">=1", - "DoWhileStatementClosingBrace": 0, - "EmptyStatement": -1, - "FinallyOpeningBrace": ">=1", - "FinallyClosingBrace": ">=1", - "ForInStatement": ">=1", - "ForInStatementExpressionOpening": "<2", - "ForInStatementExpressionClosing": -1, - "ForInStatementOpeningBrace": ">=1", - "ForInStatementClosingBrace": ">=1", - "ForStatement": ">=1", - "ForStatementExpressionOpening": "<2", - "ForStatementExpressionClosing": -1, - "ForStatementOpeningBrace": ">=1", - "ForStatementClosingBrace": ">=1", - "FunctionExpression": ">=1", "FunctionExpressionOpeningBrace": 1, - "FunctionExpressionClosingBrace": -1, - "FunctionDeclaration": ">=1", "FunctionDeclarationOpeningBrace": 1, - "FunctionDeclarationClosingBrace": ">=1", "IfStatement": 1, "IfStatementOpeningBrace": 1, "IfStatementClosingBrace": 2, - "ElseIfStatement": ">=1", "ElseIfStatementOpeningBrace": 1, "ElseIfStatementClosingBrace": 2, - "ElseStatement": ">=1", "ElseStatementOpeningBrace": 1, - "ElseStatementClosingBrace": 2, - "LogicalExpression": -1, - "ObjectExpressionOpeningBrace": ">=1", - "Property": 0, - "ReturnStatement": -1, - "SwitchOpeningBrace": ">=1", - "SwitchClosingBrace": ">=1", - "ThisExpression": 0, - "ThrowStatement": ">=1", - "TryOpeningBrace": ">=1", - "TryClosingBrace": 0, - "VariableDeclaration": ">=1", - "WhileStatement": ">=1", - "WhileStatementOpeningBrace": ">=1", - "WhileStatementClosingBrace": ">=1" + "ElseStatementClosingBrace": 2 } }, "whiteSpace": { "value": " ", "removeTrailing": 1, "before": { - "ArrayExpressionOpening": 0, - "ArrayExpressionClosing": 0, - "ArrayExpressionComma": 0, - "ArgumentComma": 0, - "ArgumentList": 0, "ArgumentListArrayExpression": 0, "ArgumentListFunctionExpression": 0, "ArgumentListObjectExpression": 0, - "AssignmentOperator": 1, - "BinaryExpression": 0, - "BinaryExpressionOperator": 1, "BlockComment": 0, - "CallExpression": -1, - "CatchParameterList": 0, - "CatchOpeningBrace": 1, - "CatchClosingBrace": 1, - "CatchKeyword": 1, - "CommaOperator": 0, - "ConditionalExpressionConsequent": 1, - "ConditionalExpressionAlternate": 1, - "DoWhileStatementOpeningBrace": 1, - "DoWhileStatementClosingBrace": 1, - "DoWhileStatementConditional": 1, - "EmptyStatement": 0, - "ExpressionClosingParentheses": 0, - "FinallyOpeningBrace": 1, - "FinallyClosingBrace": 1, - "ForInStatement": 1, - "ForInStatementExpressionOpening": 1, - "ForInStatementExpressionClosing": 0, - "ForInStatementOpeningBrace": 1, - "ForInStatementClosingBrace": 1, - "ForStatement": 1, - "ForStatementExpressionOpening": 1, - "ForStatementExpressionClosing": 0, - "ForStatementOpeningBrace": 1, - "ForStatementClosingBrace": 1, - "ForStatementSemicolon": 0, - "FunctionDeclarationOpeningBrace": 1, - "FunctionDeclarationClosingBrace": 1, - "FunctionExpressionOpeningBrace": 1, - "FunctionExpressionClosingBrace": 1, - "IfStatementConditionalOpening": 1, - "IfStatementConditionalClosing": 0, - "IfStatementOpeningBrace": 1, "IfStatementClosingBrace": 0, - "ElseStatementOpeningBrace": 1, - "ElseStatementClosingBrace": 1, - "ElseIfStatementOpeningBrace": 1, - "ElseIfStatementClosingBrace": 1, - "MemberExpressionClosing": 0, - "LineComment": 0, - "LogicalExpressionOperator": 1, - "Property": 1, - "PropertyValue": 1, - "ParameterComma": 0, - "ParameterList": 0, - "SwitchDiscriminantOpening": 1, - "SwitchDiscriminantClosing": 0, - "ThrowKeyword": 1, - "TryOpeningBrace": 1, - "TryClosingBrace": 1, - "UnaryExpressionOperator": 0, - "VariableName": 1, - "VariableValue": 1, - "WhileStatementConditionalOpening": 1, - "WhileStatementConditionalClosing": 0, - "WhileStatementOpeningBrace": 1, - "WhileStatementClosingBrace": 1 + "LineComment": 0 }, "after": { - "ArrayExpressionOpening": 0, - "ArrayExpressionClosing": 0, - "ArrayExpressionComma": 1, - "ArgumentComma": 1, - "ArgumentList": 0, "ArgumentListArrayExpression": 0, "ArgumentListFunctionExpression": 0, "ArgumentListObjectExpression": 0, - "AssignmentOperator": 1, - "BinaryExpression": 0, - "BinaryExpressionOperator": 1, - "BlockComment": 1, "CallExpression": 0, - "CatchParameterList": 0, - "CatchOpeningBrace": 1, - "CatchClosingBrace": 1, - "CatchKeyword": 1, - "CommaOperator": 1, - "ConditionalExpressionConsequent": 1, - "ConditionalExpressionTest": 1, - "DoWhileStatementOpeningBrace": 1, - "DoWhileStatementClosingBrace": 1, - "DoWhileStatementBody": 1, - "EmptyStatement": 0, - "ExpressionOpeningParentheses": 0, - "FinallyOpeningBrace": 1, - "FinallyClosingBrace": 1, - "ForInStatement": 1, - "ForInStatementExpressionOpening": 0, - "ForInStatementExpressionClosing": 1, - "ForInStatementOpeningBrace": 1, - "ForInStatementClosingBrace": 1, - "ForStatement": 1, - "ForStatementExpressionOpening": 0, - "ForStatementExpressionClosing": 1, - "ForStatementClosingBrace": 1, - "ForStatementOpeningBrace": 1, - "ForStatementSemicolon": 1, "FunctionReservedWord": 1, - "FunctionName": 0, - "FunctionExpressionOpeningBrace": 1, - "FunctionExpressionClosingBrace": 0, - "FunctionDeclarationOpeningBrace": 1, - "FunctionDeclarationClosingBrace": 1, - "IfStatementConditionalOpening": 0, - "IfStatementConditionalClosing": 1, - "IfStatementOpeningBrace": 1, - "IfStatementClosingBrace": 1, - "ElseStatementOpeningBrace": 1, - "ElseStatementClosingBrace": 1, - "ElseIfStatementOpeningBrace": 1, - "ElseIfStatementClosingBrace": 1, - "MemberExpressionOpening": 0, - "LogicalExpressionOperator": 1, - "ObjectExpressionClosingBrace": 0, - "PropertyName": 0, - "PropertyValue": 0, - "ParameterComma": 1, - "ParameterList": 0, - "SwitchDiscriminantOpening": 0, - "SwitchDiscriminantClosing": 1, - "ThrowKeyword": 1, - "TryOpeningBrace": 1, - "TryClosingBrace": 1, - "UnaryExpressionOperator": 0, - "VariableName": 1, - "WhileStatementConditionalOpening": 0, - "WhileStatementConditionalClosing": 1, - "WhileStatementOpeningBrace": 1, - "WhileStatementClosingBrace": 1 } } } From 81bfd5cf9c23ee6bc65d7608bdc18ea58d976c88 Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Fri, 8 May 2015 15:38:18 -0400 Subject: [PATCH 08/15] Add jscs lint configuration. --- linters/.jscsrc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 linters/.jscsrc diff --git a/linters/.jscsrc b/linters/.jscsrc new file mode 100644 index 0000000..030e2b8 --- /dev/null +++ b/linters/.jscsrc @@ -0,0 +1,6 @@ +{ + "preset": "airbnb", + "validateLineBreaks": null, + "disallowQuotedKeysInObjects": "allButReserved", + "validateIndentation": "\t" +} From 63f6bc96996c51ce932beccfa2133d069543c3bd Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Mon, 27 Jul 2015 17:45:57 -0400 Subject: [PATCH 09/15] Update the README. Fixes grammar mistakes, adjusts examples to better conform with guide, and removes non relevant pieces. --- README.md | 576 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 379 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index d82c5fe..8c63163 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,8 @@ *A mostly reasonable approach to JavaScript* -## Usage - -## Table of Contents +## Table of Contents 1. [Types](#types) 1. [Objects](#objects) @@ -15,31 +13,31 @@ 1. [Properties](#properties) 1. [Variables](#variables) 1. [Hoisting](#hoisting) - 1. [Conditional Expressions & Equality](#conditionals) + 1. [Comparison Operators & Equality](#comparison-operators--equality) 1. [Blocks](#blocks) 1. [Comments](#comments) 1. [Whitespace](#whitespace) - 1. [Leading Commas](#leading-commas) + 1. [Commas](#commas) 1. [Semicolons](#semicolons) - 1. [Type Casting & Coercion](#type-coercion) + 1. [Type Casting & Coercion](#type-casting--coercion) 1. [Naming Conventions](#naming-conventions) 1. [Accessors](#accessors) 1. [Constructors](#constructors) 1. [Modules](#modules) 1. [jQuery](#jquery) - 1. [ES5 Compatibility](#es5) + 1. [ECMAScript 5 Compatibility](#ecmascript-5-compatibility) 1. [Testing](#testing) 1. [Performance](#performance) 1. [Editorconfig Setup / Use](#editorconfig) 1. [Resources](#resources) 1. [In the Wild](#in-the-wild) - 1. [The JavaScript Style Guide Guide](#guide-guide) + 1. [The JavaScript Style Guide Guide](#the-javascript-style-guide-guide) 1. [Contributors](#contributors) 1. [License](#license) -## Types +## Types - - **Primitives**: When you access a primitive type you work directly on its value + - **Primitives**: When you access a primitive type you work directly on its value. + `string` + `number` @@ -55,7 +53,7 @@ console.log(foo, bar); // => 1, 9 ``` - - **Complex**: When you access a complex type you work on a reference to its value + - **Complex**: When you access a complex type you work on a reference to its value. + `object` + `array` @@ -70,9 +68,9 @@ console.log(foo[0], bar[0]); // => 9, 9 ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Objects +## Objects - Use the literal syntax for object creation. @@ -84,7 +82,7 @@ var item = {}; ``` - - Don't use [reserved words](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words) as keys. + - Don't use [reserved words](http://es5.github.io/#x7.6.1) as keys. It won't work in IE8. [More info](https://github.com/airbnb/javascript/issues/61). ```javascript // bad @@ -101,11 +99,31 @@ hidden: true }; ``` - **[[⬆]](#TOC)** -## Arrays + - Use readable synonyms in place of reserved words. + + ```javascript + // bad + var superman = { + class: 'alien' + }; + + // bad + var superman = { + klass: 'alien' + }; + + // good + var superman = { + type: 'alien' + }; + ``` + +**[⬆ back to top](#table-of-contents)** - - Use the literal syntax for array creation +## Arrays + + - Use the literal syntax for array creation. ```javascript // bad @@ -115,7 +133,7 @@ var items = []; ``` - - If you don't know array length use Array#push. + - Use Array#push instead of direct assignment to add items to an array. ```javascript var someStack = []; @@ -131,9 +149,9 @@ - When you need to copy an array use Array#slice. [jsPerf](http://jsperf.com/converting-arguments-to-an-array/7) ```javascript - var len = items.length, - itemsCopy = [], - i; + var len = items.length; + var itemsCopy = []; + var i; // bad for (i = 0; i < len; i++) { @@ -141,15 +159,24 @@ } // good - itemsCopy = Array.prototype.slice.call(items); + itemsCopy = items.slice(); + ``` + + - To convert an array-like object to an array, use Array#slice. + + ```javascript + function trigger() { + var args = Array.prototype.slice.call(arguments); + ... + } ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Strings +## Strings - - Use single quotes `''` for strings + - Use single quotes `''` for strings. ```javascript // bad @@ -166,16 +193,16 @@ ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Functions +## Functions - Function expressions: ```javascript // anonymous function as event handler - $el.on('click', function () { + $el.on('click', function() { return true; }); @@ -185,12 +212,12 @@ }); // anonymous function as method - MyObject.prototype.isTrue = function () { + MyObject.prototype.isTrue = function() { return true; }; // immediately-invoked function expression (IIFE) - (function () { + (function() { console.log('Welcome to the Internet. Please follow me.'); })(); ``` @@ -206,7 +233,7 @@ ``` - Never declare a function in a non-function block (if, while, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears. - - **Note:** ECMA-262 defines a `block` as a list of statements. A function declartion is not a statement. [Read ECMA-262's note on this issue](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf#page=97). + - **Note:** ECMA-262 defines a `block` as a list of statements. A function declaration is not a statement. [Read ECMA-262's note on this issue](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf#page=97). ```javascript // bad @@ -217,14 +244,15 @@ } // good + var test; if (currentUser) { - var test = function test() { + test = function test() { console.log('Yup.'); }; } ``` - - Never name a parameter `arguments`, this will take precedence over the `arguments` object that is given to every function scope. + - Never name a parameter `arguments`. This will take precedence over the `arguments` object that is given to every function scope. ```javascript // bad @@ -238,11 +266,11 @@ } ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Properties +## Properties - Use dot notation when accessing properties. @@ -274,10 +302,10 @@ var isJedi = getProp('jedi'); ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Variables +## Variables - Always use `var` to declare variables. Not doing so will result in global variables. We want to avoid polluting the global namespace. Captain Planet warned us of that. @@ -289,7 +317,10 @@ var superPower = new SuperPower(); ``` - - Use multiple `var` declarations for multiple variables and declare each variable on a newline. Justification: http://benalman.com/news/2012/05/multiple-var-statements-javascript + - Use one `var` declaration per variable. + It's easier to add new variable declarations this way, and you never have + to worry about swapping out a `;` for a `,` or introducing punctuation-only + diffs. ```javascript // bad @@ -297,6 +328,12 @@ goSportsTeam = true, dragonball = 'z'; + // bad + // (compare to above, and try to spot the mistake) + var items = getItems(), + goSportsTeam = true; + dragonball = 'z'; + // good var items = getItems(); var goSportsTeam = true; @@ -317,7 +354,7 @@ ```javascript // bad - function () { + function() { test(); console.log('doing stuff..'); @@ -333,7 +370,7 @@ } // good - function () { + function() { var name = getName(); test(); @@ -348,35 +385,40 @@ return name; } - // bad - function () { + // bad - unnecessary function call + function() { var name = getName(); if (!arguments.length) { return false; } + this.setFirstName(name); + return true; } // good - function () { + function() { + var name; + if (!arguments.length) { return false; } - var name = getName(); + name = getName(); + this.setFirstName(name); return true; } ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Hoisting +## Hoisting - - Variable declarations get hoisted to the top of their scope, their assignment does not. + - Variable declarations get hoisted to the top of their scope, but their assignment does not. ```javascript // we know this wouldn't work (assuming there @@ -394,9 +436,9 @@ var declaredButNotAssigned = true; } - // The interpretor is hoisting the variable - // declaration to the top of the scope. - // Which means our example could be rewritten as: + // The interpreter is hoisting the variable + // declaration to the top of the scope, + // which means our example could be rewritten as: function example() { var declaredButNotAssigned; console.log(declaredButNotAssigned); // => undefined @@ -412,7 +454,7 @@ anonymous(); // => TypeError anonymous is not a function - var anonymous = function () { + var anonymous = function() { console.log('anonymous function expression'); }; } @@ -431,19 +473,18 @@ var named = function superPower() { console.log('Flying'); }; + } + // the same is true when the function name + // is the same as the variable name. + function example() { + console.log(named); // => undefined - // the same is true when the function name - // is the same as the variable name. - function example() { - console.log(named); // => undefined - - named(); // => TypeError named is not a function + named(); // => TypeError named is not a function - var named = function named() { - console.log('named'); - }; - } + var named = function named() { + console.log('named'); + }; } ``` @@ -459,22 +500,22 @@ } ``` - - For more information refer to [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) by [Ben Cherry](http://www.adequatelygood.com/) + - For more information refer to [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) by [Ben Cherry](http://www.adequatelygood.com/). - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Conditional Expressions & Equality +## Comparison Operators & Equality - Use `===` and `!==` over `==` and `!=`. - - Conditional expressions are evaluated using coercion with the `ToBoolean` method and always follow these simple rules: + - Conditional statements such as the `if` statement evaluate their expression using coercion with the `ToBoolean` abstract method and always follow these simple rules: + **Objects** evaluate to **true** + **Undefined** evaluates to **false** + **Null** evaluates to **false** + **Booleans** evaluate to **the value of the boolean** - + **Numbers** evalute to **false** if **+0, -0, or NaN**, otherwise **true** + + **Numbers** evaluate to **false** if **+0, -0, or NaN**, otherwise **true** + **Strings** evaluate to **false** if an empty string `''`, otherwise **true** ```javascript @@ -508,12 +549,12 @@ } ``` - - For more information see [Truth Equality and JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll + - For more information see [Truth Equality and JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll. - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Blocks +## Blocks - Use braces with all multi-line blocks. @@ -522,37 +563,60 @@ if (test) return false; + // acceptable (only for very simple statements and early function return) + if (test) return false; + // good if (test) { return false; } - // good - function () { return false; } + // bad + function() { return false; } // good - function () { + function() { return false; } + ``` - // acceptable (only for very simple statements and early function return) - if (test) return false; + - If you're using multi-line blocks with `if` and `else`, put `else` on the same line as your + `if` block's closing brace. + + ```javascript + // bad + if (test) { + thing1(); + thing2(); + } + else { + thing3(); + } + + // good + if (test) { + thing1(); + thing2(); + } else { + thing3(); + } ``` - **[[⬆]](#TOC)** + +**[⬆ back to top](#table-of-contents)** -## Comments +## Comments - - Use `/** ... */` for multiline comments. Include a description, specify types and values for all parameters and return values. + - Use `/** ... */` for multi-line comments. Include a description, specify types and values for all parameters and return values. ```javascript // bad // make() returns a new element // based on the passed in tag name // - // @param tag - // @return element + // @param {String} tag + // @return {Element} element function make(tag) { // ...stuff... @@ -565,8 +629,8 @@ * make() returns a new element * based on the passed in tag name * - * @param tag - * @return element + * @param {String} tag + * @return {Element} element */ function make(tag) { @@ -576,7 +640,7 @@ } ``` - - Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an emptyline before the comment. + - Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment. ```javascript // bad @@ -606,29 +670,56 @@ } ``` - **[[⬆]](#TOC)** + - Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME -- need to figure this out` or `TODO -- need to implement`. + + - Use `// FIXME:` to annotate problems. + + ```javascript + function Calculator() { + + // FIXME: shouldn't use a global here + total = 0; + + return this; + } + ``` + + - Use `// TODO:` to annotate solutions to problems. + + ```javascript + function Calculator() { + + // TODO: total should be configurable by an options param + this.total = 0; + + return this; + } + ``` + +**[⬆ back to top](#table-of-contents)** -## Whitespace +## Whitespace - Use tabs. One per indent level. This allows developers to choose their preferred display width. ```javascript // bad - function () { + function() { ∙∙var name; } // bad - function () { + function() { ∙∙∙∙var name; } - // good - function () { - var name; - } + // good + function() { + var name; + } ``` + - Place 1 space before the leading brace. ```javascript @@ -655,38 +746,63 @@ }); ``` - - Place 1 space before anonymous function parenthesis. + - Place 1 space before the opening parenthesis in control statements (`if`, `while` etc.). Place no space before the argument list in function calls and declarations. ```javascript - // bad - function() { - var name; - } - - // good - function () { - var name; - } + // bad + if(isJedi) { + fight (); + } + + // good + if (isJedi) { + fight(); + } + + // bad + function fight () { + console.log ('Swooosh!'); + } + + // good + function fight() { + console.log('Swooosh!'); + } ``` - - Place an empty newline at the end of the file. + - Set off operators with spaces. ```javascript // bad - (function (global) { - // ...stuff... - })(this); + var x=y+5; + + // good + var x = y + 5; ``` + - End files with a single newline character. + ```javascript - // good - (function (global) { + // bad + (function(global) { // ...stuff... })(this); + ``` + ```javascript + // bad + (function(global) { + // ...stuff... + })(this);↵ + ↵ ``` - **[[⬆]](#TOC)** + ```javascript + // good + (function(global) { + // ...stuff... + })(this);↵ + ``` - Use indentation when making long method chains. Long method chains should be avoided except in cases of a performance benefit or significant readability benefit. @@ -719,11 +835,27 @@ .call(tron.led); ``` -## Leading Commas +**[⬆ back to top](#table-of-contents)** + +## Commas - - **Nope.** + - Leading commas: **Nope.** ```javascript + // bad + var story = [ + once + , upon + , aTime + ]; + + // good + var story = [ + once, + upon, + aTime + ]; + // bad var hero = { firstName: 'Bob' @@ -741,31 +873,67 @@ }; ``` - **[[⬆]](#TOC)** + - Additional trailing comma: **Nope.** This can cause problems with IE6/7 and IE9 if it's in quirksmode. Also, in some implementations of ES3 would add length to an array if it had an additional trailing comma. This was clarified in ES5 ([source](http://es5.github.io/#D)): + > Edition 5 clarifies the fact that a trailing comma at the end of an ArrayInitialiser does not add to the length of the array. This is not a semantic change from Edition 3 but some implementations may have previously misinterpreted this. -## Semicolons + ```javascript + // bad + var hero = { + firstName: 'Kevin', + lastName: 'Flynn', + }; + + var heroes = [ + 'Batman', + 'Superman', + ]; + + // good + var hero = { + firstName: 'Kevin', + lastName: 'Flynn' + }; + + var heroes = [ + 'Batman', + 'Superman' + ]; + ``` + +**[⬆ back to top](#table-of-contents)** + + +## Semicolons - **Yup.** ```javascript // bad - (function () { + (function() { var name = 'Skywalker' return name })() // good - (function () { + (function() { + var name = 'Skywalker'; + return name; + })(); + + // good (guards against the function becoming an argument when two files with IIFEs are concatenated) + ;(function() { var name = 'Skywalker'; return name; })(); ``` - **[[⬆]](#TOC)** + [Read more](http://stackoverflow.com/a/7365214/1712802). +**[⬆ back to top](#table-of-contents)** -## Type Casting & Coercion + +## Type Casting & Coercion - Perform type coercion at the beginning of the statement. - Strings: @@ -787,7 +955,6 @@ ``` - Use `parseInt` for Numbers and always with a radix for type casting. - - If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need to use Bitshift for [performance reasons](http://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you're doing. ```javascript var inputValue = '4'; @@ -809,7 +976,11 @@ // good var val = parseInt(inputValue, 10); + ``` + + - If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need to use Bitshift for [performance reasons](http://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you're doing. + ```javascript // good /** * parseInt was the reason my code was slow. @@ -819,6 +990,14 @@ var val = inputValue >> 0; ``` + - **Note:** Be careful when using bitshift operations. Numbers are represented as [64-bit values](http://es5.github.io/#x4.3.19), but Bitshift operations always return a 32-bit integer ([source](http://es5.github.io/#x11.7)). Bitshift can lead to unexpected behavior for integer values larger than 32 bits. [Discussion](https://github.com/airbnb/javascript/issues/109). Largest signed 32-bit Int is 2,147,483,647: + + ```javascript + 2147483647 >> 0 //=> 2147483647 + 2147483648 >> 0 //=> -2147483648 + 2147483649 >> 0 //=> -2147483647 + ``` + - Booleans: ```javascript @@ -834,10 +1013,10 @@ var hasAge = !!age; ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Naming Conventions +## Naming Conventions - Avoid single letter names. Be descriptive with your naming. @@ -853,27 +1032,27 @@ } ``` - - Use camelCase when naming objects, functions, and instances + - Use camelCase when naming objects, functions, and instances. ```javascript // bad var OBJEcttsssss = {}; var this_is_my_object = {}; - var this-is-my-object = {}; - function c() {}; + var o = {}; + function c() {} var u = new user({ name: 'Bob Parr' }); // good var thisIsMyObject = {}; - function thisIsMyFunction () {}; + function thisIsMyFunction () {} var user = new User({ name: 'Bob Parr' }); ``` - - Use PascalCase when naming constructors or classes + - Use PascalCase when naming constructors or classes. ```javascript // bad @@ -895,7 +1074,7 @@ }); ``` - - Use a leading underscore `_` when naming private properties + - Use a leading underscore `_` when naming private properties. ```javascript // bad @@ -910,25 +1089,25 @@ ```javascript // bad - function () { + function() { var that = this; - return function () { + return function() { console.log(that); }; } // bad - function () { + function() { var _this = this; - return function () { + return function() { console.log(_this); }; } // good - function () { + function() { var self = this; - return function () { + return function() { console.log(self); }; } @@ -938,7 +1117,7 @@ ```javascript // bad - var log = function (msg) { + var log = function(msg) { console.log(msg); }; @@ -948,13 +1127,13 @@ }; ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Accessors +## Accessors - - Accessor functions for properties are not required - - If you do make accessor functions use getVal() and setVal('hello') + - Accessor functions for properties are not required. + - If you do make accessor functions use getVal() and setVal('hello'). ```javascript // bad @@ -970,7 +1149,7 @@ dragon.setAge(25); ``` - - If the property is a boolean, use isVal() or hasVal() + - If the property is a boolean, use isVal() or hasVal(). ```javascript // bad @@ -993,19 +1172,19 @@ this.set('lightsaber', lightsaber); } - Jedi.prototype.set = function (key, val) { + Jedi.prototype.set = function(key, val) { this[key] = val; }; - Jedi.prototype.get = function (key) { + Jedi.prototype.get = function(key) { return this[key]; }; ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Constructors +## Constructors - Assign methods to the prototype object, instead of overwriting the prototype with a new object. Overwriting the prototype makes inheritance impossible: by resetting the prototype you'll overwrite the base! @@ -1039,26 +1218,26 @@ ```javascript // bad - Jedi.prototype.jump = function () { + Jedi.prototype.jump = function() { this.jumping = true; return true; }; - Jedi.prototype.setHeight = function (height) { + Jedi.prototype.setHeight = function(height) { this.height = height; }; var luke = new Jedi(); luke.jump(); // => true - luke.setHeight(20) // => undefined + luke.setHeight(20); // => undefined // good - Jedi.prototype.jump = function () { + Jedi.prototype.jump = function() { this.jumping = true; return this; }; - Jedi.prototype.setHeight = function (height) { + Jedi.prototype.setHeight = function(height) { this.height = height; return this; }; @@ -1087,19 +1266,19 @@ }; ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Modules +## Modules - Use AMD. Justification: - http://requirejs.org/docs/whyamd.html - https://gist.github.com/4686136 - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## jQuery +## jQuery - Prefix jQuery object variables with a `$`. @@ -1138,12 +1317,12 @@ } ``` - - For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > .ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16) + - For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16) - Use `find` with scoped jQuery object queries. ```javascript // bad - $('.sidebar', 'ul').hide(); + $('ul', '.sidebar').hide(); // bad $('.sidebar').find('ul').hide(); @@ -1161,30 +1340,30 @@ $($sidebar[0]).find('ul'); ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## ECMAScript 5 Compatibility +## ECMAScript 5 Compatibility - - Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](http://kangax.github.com/es5-compat-table/) + - Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](http://kangax.github.com/es5-compat-table/). - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Testing +## Testing - **Yup.** ```javascript - function () { + function() { return true; } ``` - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Performance +## Performance - [On Layout & Web Performance](http://kellegous.com/j/2013/01/26/layout-performance/) - [String vs Array Concat](http://jsperf.com/string-vs-array-concat/2) @@ -1195,41 +1374,53 @@ - [Long String Concatenation](http://jsperf.com/ya-string-concat) - Loading... - **[[⬆]](#TOC)** - +**[⬆ back to top](#table-of-contents)** + ## Editorconfig Setup / Use - - Usually for a project with more than one developer involved, it is essentially important for the project to define - and maintain a consistent coding style. Most code editors and IDEs, such as Vim, Emacs, Code::Blocks, provide settings - related to coding styles, such as the width of tab, the size of indentation, end of line, etc. However, it is hard to - provide the same settings for different Editors and IDEs: we have to maintain many config files for different editors - and IDEs, such as .vimrc for Vim, .emacs for Emacs. In order to solve this, EditorConfig was born. By defining coding - style in files named .editorconfig, the EditorConfig plugins for different editors and IDEs will automatically adjust + - Usually for a project with more than one developer involved, it is essentially important for the project to define + and maintain a consistent coding style. Most code editors and IDEs, such as Vim, Emacs, Code::Blocks, provide settings + related to coding styles, such as the width of tab, the size of indentation, end of line, etc. However, it is hard to + provide the same settings for different Editors and IDEs: we have to maintain many config files for different editors + and IDEs, such as .vimrc for Vim, .emacs for Emacs. In order to solve this, EditorConfig was born. By defining coding + style in files named .editorconfig, the EditorConfig plugins for different editors and IDEs will automatically adjust your coding style. - - To use EditorConfig, you have to download the corresponding [EditorConfig plugins](http://editorconfig.org/#download) for your Editor or IDE. - Follow the installation instructions to install them. + - To use EditorConfig, you have to download the corresponding [EditorConfig plugins](http://editorconfig.org/#download) for your Editor or IDE. + Follow the installation instructions to install them. - The "base" .editorconfig file goes in the root directory. You can have other config files in specific folders if wanted. The only difference would be at the top of the file to remove root = true from any file that isn't the root. - - **[[⬆]](#TOC)** +**[⬆ back to top](#table-of-contents)** -## Resources + +## Resources **Read This** - [Annotated ECMAScript 5.1](http://es5.github.com/) -**Other Styleguides** +**Other Style Guides** - [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) - [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines) - [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwldrn/idiomatic.js/) + - [JavaScript Standard Style](https://github.com/feross/standard) **Other Styles** - [Naming this in nested functions](https://gist.github.com/4135065) - Christian Johansen + - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen + - [Popular JavaScript Coding Conventions on Github](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun + - [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman + +**Further Reading** + + - [Understanding JavaScript Closures](http://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll + - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer + - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz + - [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban + - [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock **Books** @@ -1241,6 +1432,14 @@ - [JavaScript Web Applications](http://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw - [Pro JavaScript Techniques](http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig - [Smashing Node.js: JavaScript Everywhere](http://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch + - [Secrets of the JavaScript Ninja](http://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault + - [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg + - [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy + - [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon + - [Third Party JavaScript](http://manning.com/vinegar/) - Ben Vinegar and Anton Kovalyov + - [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman + - [Eloquent JavaScript](http://eloquentjavascript.net) - Marijn Haverbeke + - [You Don't Know JS](https://github.com/getify/You-Dont-Know-JS) - Kyle Simpson **Blogs** @@ -1256,33 +1455,18 @@ - [Dustin Diaz](http://dustindiaz.com/) - [nettuts](http://net.tutsplus.com/?s=javascript) - **[[⬆]](#TOC)** - -## In the Wild +**Podcasts** - This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list. + - [JavaScript Jabber](http://devchat.tv/js-jabber/) - - **Airbnb**: [airbnb/javascript](//github.com/airbnb/javascript) - - **ExactTarget**: [ExactTarget/javascript](//github.com/ExactTarget/javascript) - - **American Insitutes for Research**: [AIRAST/javascript](//github.com/AIRAST/javascript) - - **GoCardless**: [gocardless/javascript](//github.com/gocardless/javascript) - - **GoodData**: [gooddata/gdc-js-style](//github.com/gooddata/gdc-js-style) - - **How About We**: [howaboutwe/javascript](//github.com/howaboutwe/javascript) - - **MinnPost**: [MinnPost/javascript](//github.com/MinnPost/javascript) - - **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript) - - **Razorfish**: [razorfish/javascript-style-guide](//github.com/razorfish/javascript-style-guide) - - **Shutterfly**: [shutterfly/javascript](//github.com/shutterfly/javascript) -## The JavaScript Style Guide Guide +**[⬆ back to top](#table-of-contents)** - - [Reference](//github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide) +## The JavaScript Style Guide Guide -## Contributors + - [Reference](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide) - - [View Contributors](https://github.com/airbnb/javascript/graphs/contributors) - - -## License +## License (The MIT License) @@ -1323,6 +1507,4 @@ Neither the name of the copyright holder nor the names of its contributors may b THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**[[⬆]](#TOC)** - - +**[⬆ back to top](#table-of-contents)** From 7f8963d0d28599a80d86de08683b58b461cb1be2 Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Fri, 7 Aug 2015 11:32:51 -0400 Subject: [PATCH 10/15] Readd anonymous function paren space. --- README.md | 56 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 8c63163..8d7adc0 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ ```javascript // anonymous function as event handler - $el.on('click', function() { + $el.on('click', function () { return true; }); @@ -217,7 +217,7 @@ }; // immediately-invoked function expression (IIFE) - (function() { + (function () { console.log('Welcome to the Internet. Please follow me.'); })(); ``` @@ -354,7 +354,7 @@ ```javascript // bad - function() { + function () { test(); console.log('doing stuff..'); @@ -370,7 +370,7 @@ } // good - function() { + function () { var name = getName(); test(); @@ -386,7 +386,7 @@ } // bad - unnecessary function call - function() { + function () { var name = getName(); if (!arguments.length) { @@ -399,7 +399,7 @@ } // good - function() { + function () { var name; if (!arguments.length) { @@ -572,10 +572,10 @@ } // bad - function() { return false; } + function () { return false; } // good - function() { + function () { return false; } ``` @@ -705,17 +705,17 @@ ```javascript // bad - function() { + function () { ∙∙var name; } // bad - function() { + function () { ∙∙∙∙var name; } // good - function() { + function () { var name; } ``` @@ -770,6 +770,20 @@ } ``` + - Place 1 space before anonymous function parenthesis. + + ```javascript + // bad + function() { + var name; + } + + // good + function () { + var name; + } + ``` + - Set off operators with spaces. ```javascript @@ -910,19 +924,19 @@ ```javascript // bad - (function() { + (function () { var name = 'Skywalker' return name })() // good - (function() { + (function () { var name = 'Skywalker'; return name; })(); // good (guards against the function becoming an argument when two files with IIFEs are concatenated) - ;(function() { + ;(function () { var name = 'Skywalker'; return name; })(); @@ -1089,25 +1103,25 @@ ```javascript // bad - function() { + function () { var that = this; - return function() { + return function () { console.log(that); }; } // bad - function() { + function () { var _this = this; - return function() { + return function () { console.log(_this); }; } // good - function() { + function () { var self = this; - return function() { + return function () { console.log(self); }; } @@ -1355,7 +1369,7 @@ - **Yup.** ```javascript - function() { + function () { return true; } ``` From 3073ca15e9746f53e7573fe0d53cc66c55d822b7 Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Tue, 18 Aug 2015 09:56:09 -0400 Subject: [PATCH 11/15] Fix paren spacing on unamed functions. --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8d7adc0..8999ee5 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ }); // anonymous function as method - MyObject.prototype.isTrue = function() { + MyObject.prototype.isTrue = function () { return true; }; @@ -454,7 +454,7 @@ anonymous(); // => TypeError anonymous is not a function - var anonymous = function() { + var anonymous = function () { console.log('anonymous function expression'); }; } @@ -774,7 +774,7 @@ ```javascript // bad - function() { + function () { var name; } @@ -798,14 +798,14 @@ ```javascript // bad - (function(global) { + (function (global) { // ...stuff... })(this); ``` ```javascript // bad - (function(global) { + (function (global) { // ...stuff... })(this);↵ ↵ @@ -813,7 +813,7 @@ ```javascript // good - (function(global) { + (function (global) { // ...stuff... })(this);↵ ``` @@ -1131,7 +1131,7 @@ ```javascript // bad - var log = function(msg) { + var log = function (msg) { console.log(msg); }; @@ -1186,11 +1186,11 @@ this.set('lightsaber', lightsaber); } - Jedi.prototype.set = function(key, val) { + Jedi.prototype.set = function (key, val) { this[key] = val; }; - Jedi.prototype.get = function(key) { + Jedi.prototype.get = function (key) { return this[key]; }; ``` @@ -1232,12 +1232,12 @@ ```javascript // bad - Jedi.prototype.jump = function() { + Jedi.prototype.jump = function () { this.jumping = true; return true; }; - Jedi.prototype.setHeight = function(height) { + Jedi.prototype.setHeight = function (height) { this.height = height; }; @@ -1246,12 +1246,12 @@ luke.setHeight(20); // => undefined // good - Jedi.prototype.jump = function() { + Jedi.prototype.jump = function () { this.jumping = true; return this; }; - Jedi.prototype.setHeight = function(height) { + Jedi.prototype.setHeight = function (height) { this.height = height; return this; }; From 6bac5d9108839d76de3f593bc68e7a082d8e3c55 Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Tue, 18 Aug 2015 09:57:21 -0400 Subject: [PATCH 12/15] Fix rogue space and missing semi. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8999ee5..3108094 100644 --- a/README.md +++ b/README.md @@ -1060,7 +1060,7 @@ // good var thisIsMyObject = {}; - function thisIsMyFunction () {} + function thisIsMyFunction() {}; var user = new User({ name: 'Bob Parr' }); From 80258e406046b89a938acd2d2cdd9e0c13541e04 Mon Sep 17 00:00:00 2001 From: Gary Borton Date: Tue, 18 Aug 2015 11:10:25 -0400 Subject: [PATCH 13/15] Another rogue space. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3108094..0a6c785 100644 --- a/README.md +++ b/README.md @@ -774,7 +774,7 @@ ```javascript // bad - function () { + function() { var name; } From 3cc8247d65fd6cb30c836b271ee9a55ba346e586 Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Thu, 8 Oct 2015 17:45:25 -0400 Subject: [PATCH 14/15] 5 JSCS rules you should be using today --- linters/.jscsrc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/linters/.jscsrc b/linters/.jscsrc index 030e2b8..0118b94 100644 --- a/linters/.jscsrc +++ b/linters/.jscsrc @@ -1,6 +1,17 @@ { - "preset": "airbnb", - "validateLineBreaks": null, - "disallowQuotedKeysInObjects": "allButReserved", - "validateIndentation": "\t" -} + "preset": "airbnb", + "disallowTabs": false, + "validateLineBreaks": null, + "validateIndentation": "\t", + "disallowTrailingComma": true, + "disallowTrailingWhitespace": "ignoreEmptyLines", + "requireSpacesInAnonymousFunctionExpression": { + "beforeOpeningRoundBrace": true, + "beforeOpeningCurlyBrace": true + }, + "requireSpacesInFunction": { + "beforeOpeningRoundBrace": true, + "beforeOpeningCurlyBrace": true + }, + "disallowQuotedKeysInObjects": "allButReserved", +} \ No newline at end of file From 4a8459d92a74c7922138cfe110e65927b6aaad9d Mon Sep 17 00:00:00 2001 From: svc-scm <48930134+svc-scm@users.noreply.github.com> Date: Sat, 12 Feb 2022 07:29:37 -0800 Subject: [PATCH 15/15] Updated/Added CODEOWNERS with ECCN --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..522fa4a --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. +#ECCN:Open Source