diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..51dfc8fe4d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +; EditorConfig is awesome: http://EditorConfig.org + +; top-most EditorConfig file +root = true + +; Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..b35d54c79d --- /dev/null +++ b/.jshintrc @@ -0,0 +1,27 @@ +{ + "browser": true, + "jquery": true, + "camelcase": true, + "eqeqeq": true, + "eqnull": true, + "indent": 4, + "latedef": true, + "newcap": true, + "quotmark": "single", + "trailing": true, + "undef": true, + "unused": true, + "curly": true, + "evil": true, + "forin": true, + "immed": true, + "noarg": true, + "noempty": true, + "nonew": true, + "nomen": true, + "onevar": true, + "strict": true, + "unused": true, + "white": true, + "node": true +} diff --git a/README.md b/README.md index 9ffa524ba4..1c50a7d7ee 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -# Airbnb JavaScript Style Guide() { +# Apontador JavaScript Style Guide() { *A mostly reasonable approach to JavaScript* +Note: this guideline is based on [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript). ## Table of Contents + 1. [JSHint](#jshint) 1. [Types](#types) 1. [Objects](#objects) 1. [Arrays](#arrays) @@ -12,7 +14,6 @@ 1. [Functions](#functions) 1. [Properties](#properties) 1. [Variables](#variables) - 1. [Hoisting](#hoisting) 1. [Conditional Expressions & Equality](#conditionals) 1. [Blocks](#blocks) 1. [Comments](#comments) @@ -28,6 +29,7 @@ 1. [ES5 Compatibility](#es5) 1. [Testing](#testing) 1. [Performance](#performance) + 1. [Hoisting](#hoisting) 1. [Resources](#resources) 1. [In the Wild](#in-the-wild) 1. [Translation](#translation) @@ -35,6 +37,11 @@ 1. [Contributors](#contributors) 1. [License](#license) +## JSHint + +Most of the rules documented here can be detected by [JSHint](http://jshint.com). +So running *JSHint*, with our [.jshintrc](.jshintrc), before adding code to this repository is the best way to start. + ## Types - **Primitives**: When you access a primitive type you work directly on its value @@ -82,7 +89,7 @@ var item = {}; ``` - - Don't use [reserved words](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words) as keys. + - Avoid wrap object keys with quotes, avoid also the [reserved words](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words). ```javascript // bad @@ -92,11 +99,34 @@ private: true }; + // bad for our conventions (doesn't include JSON callback) + var superman = { + 'foo': 'superhero', + 'bar': { clark: 'kent' } + }; + + // good + var superman = { + around: 'superhero', + the: { clark: 'kent' }, + world: true + }; + + // bad + var superman = { + around: 'superhero', + the: { clark: 'kent', lois: 'lane' }, + world: true + }; + // good var superman = { - klass: 'superhero', - defaults: { clark: 'kent' }, - hidden: true + around: 'superhero', + the: { + clark: 'kent', + lois: 'lane' + }, + world: true }; ``` **[[⬆]](#TOC)** @@ -172,7 +202,7 @@ var fullName = 'Bob ' + this.lastName; ``` - - Strings longer than 80 characters should be written across multiple lines using string concatenation. + - Strings longer than 80 characters should be written in array and concatenated with `join()`. - Note: If overused, long strings with concatenation could impact performance. [jsPerf](http://jsperf.com/ya-string-concat) & [Discussion](https://github.com/airbnb/javascript/issues/40) ```javascript @@ -189,12 +219,14 @@ // good - var 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.'; + var 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.' + ].join(''); ``` - 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). @@ -254,14 +286,14 @@ }; // named function expression - var named = function named() { + function named() { return true; - }; + } // immediately-invoked function expression (IIFE) (function() { console.log('Welcome to the Internet. Please follow me.'); - })(); + }()); ``` - 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. @@ -276,10 +308,8 @@ } // good - if (currentUser) { - var test = function test() { - console.log('Yup.'); - }; + function test() { + console.log('Nope.'); } ``` @@ -338,6 +368,20 @@ ## Variables + - Use `window` for global variables + + ```javascript + //bad + function foo() { + myGlobal = 1; + } + + //good + function foo() { + window.myGlobal = 1; + } + ``` + - 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. ```javascript @@ -444,98 +488,6 @@ **[[⬆]](#TOC)** - -## Hoisting - - - Variable declarations get hoisted to the top of their scope, their assignment does not. - - ```javascript - // we know this wouldn't work (assuming there - // is no notDefined global variable) - function example() { - console.log(notDefined); // => throws a ReferenceError - } - - // creating a variable declaration after you - // reference the variable will work due to - // variable hoisting. Note: the assignment - // value of `true` is not hoisted. - function example() { - console.log(declaredButNotAssigned); // => undefined - var declaredButNotAssigned = true; - } - - // 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 - declaredButNotAssigned = true; - } - ``` - - - Anonymous function expressions hoist their variable name, but not the function assignment. - - ```javascript - function example() { - console.log(anonymous); // => undefined - - anonymous(); // => TypeError anonymous is not a function - - var anonymous = function() { - console.log('anonymous function expression'); - }; - } - ``` - - - Named function expressions hoist the variable name, not the function name or the function body. - - ```javascript - function example() { - console.log(named); // => undefined - - named(); // => TypeError named is not a function - - superPower(); // => ReferenceError superPower is not defined - - 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 - - named(); // => TypeError named is not a function - - var named = function named() { - console.log('named'); - }; - } - } - ``` - - - Function declarations hoist their name and the function body. - - ```javascript - function example() { - superPower(); // => Flying - - function superPower() { - console.log('Flying'); - } - } - ``` - - - 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)** - - - ## Conditional Expressions & Equality - Use `===` and `!==` over `==` and `!=`. @@ -586,19 +538,19 @@ ## Blocks - - Use braces with all multi-line blocks. + - Always use braces. ```javascript // bad if (test) return false; - // good + // bad if (test) return false; // good if (test) { - return false; + return false; } // bad @@ -606,7 +558,7 @@ // good function() { - return false; + return false; } ``` @@ -615,15 +567,12 @@ ## Comments - - Use `/** ... */` for multiline comments. Include a description, specify types and values for all parameters and return values. + - Use `/** ... */` for multiline comments. ```javascript // bad // make() returns a new element // based on the passed in tag name - // - // @param tag - // @return element function make(tag) { // ...stuff... @@ -635,9 +584,6 @@ /** * make() returns a new element * based on the passed in tag name - * - * @param tag - * @return element */ function make(tag) { @@ -677,43 +623,17 @@ } ``` - - 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; - } - ``` - **[[⬆]](#TOC)** ## Whitespace - - Use soft tabs set to 2 spaces + - Use soft tabs set to 4 spaces ```javascript // bad function() { - ∙∙∙∙var name; + ∙∙var name; } // bad @@ -723,7 +643,7 @@ // good function() { - ∙∙var name; + ∙∙∙∙var name; } ``` - Place 1 space before the leading brace. @@ -757,14 +677,14 @@ // bad (function(global) { // ...stuff... - })(this); + }(this)); ``` ```javascript // good (function(global) { // ...stuff... - })(this); + }(this)); ``` @@ -845,19 +765,13 @@ (function() { var name = 'Skywalker' return name - })() + }()) // good (function() { var name = 'Skywalker'; return name; - })(); - - // good - ;(function() { - var name = 'Skywalker'; - return name; - })(); + }()); ``` **[[⬆]](#TOC)** @@ -885,7 +799,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'; @@ -907,14 +820,6 @@ // good var val = parseInt(inputValue, 10); - - // good - /** - * parseInt was the reason my code was slow. - * Bitshifting the String to coerce it to a - * Number made it a lot faster. - */ - var val = inputValue >> 0; ``` - Booleans: @@ -993,18 +898,18 @@ }); ``` - - Use a leading underscore `_` when naming private properties + - Never use a leading underscore `_` when naming private properties ```javascript // bad this.__firstName__ = 'Panda'; this.firstName_ = 'Panda'; - // good + // bad this._firstName = 'Panda'; ``` - - When saving a reference to `this` use `_this`. + - When saving a reference to `this` use `self`. ```javascript // bad @@ -1015,7 +920,7 @@ }; } - // bad + // good function() { var that = this; return function() { @@ -1032,20 +937,6 @@ } ``` - - Name your functions. This is helpful for stack traces. - - ```javascript - // bad - var log = function(msg) { - console.log(msg); - }; - - // good - var log = function log(msg) { - console.log(msg); - }; - ``` - **[[⬆]](#TOC)** @@ -1317,91 +1208,21 @@ **[[⬆]](#TOC)** +You must take a look: +### [Hoisting](resources.md#read-this) +### [Resources](resources.md) -## Resources - - -**Read This** - - - [Annotated ECMAScript 5.1](http://es5.github.com/) - -**Other Styleguides** - - - [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/) - -**Other Styles** - - - [Naming this in nested functions](https://gist.github.com/4135065) - Christian Johansen - - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - -**Books** - - - [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford - - [JavaScript Patterns](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov - - [Pro JavaScript Design Patterns](http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz - - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders - - [Maintainable JavaScript](http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas - - [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 - -**Blogs** - - - [DailyJS](http://dailyjs.com/) - - [JavaScript Weekly](http://javascriptweekly.com/) - - [JavaScript, JavaScript...](http://javascriptweblog.wordpress.com/) - - [Bocoup Weblog](http://weblog.bocoup.com/) - - [Adequately Good](http://www.adequatelygood.com/) - - [NCZOnline](http://www.nczonline.net/) - - [Perfection Kills](http://perfectionkills.com/) - - [Ben Alman](http://benalman.com/) - - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/) - - [Dustin Diaz](http://dustindiaz.com/) - - [nettuts](http://net.tutsplus.com/?s=javascript) - - **[[⬆]](#TOC)** - -## In the Wild - - 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. - - - **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript) - - **American Insitutes for Research**: [AIRAST/javascript](https://github.com/AIRAST/javascript) - - **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript) - - **GeneralElectric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript) - - **GoodData**: [gooddata/gdc-js-style](https://github.com/gooddata/gdc-js-style) - - **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript) - - **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript) - - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript) - - **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript) - - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide) - - **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript) - - **Userify**: [userify/javascript](https://github.com/userify/javascript) - - **Zillow**: [zillow/javascript](https://github.com/zillow/javascript) - -## Translation - - This style guide is also available in other languages: - - - :de: **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide) - - :jp: **Japanese**: [mitsuruog/javacript-style-guide](https://github.com/mitsuruog/javacript-style-guide) - - :br: **Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide) - -## The JavaScript Style Guide Guide - - - [Reference](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide) ## Contributors - - [View Contributors](https://github.com/airbnb/javascript/graphs/contributors) - + - [View Contributors](https://github.com/apontador/javascript/graphs/contributors) ## License (The MIT License) +Copyright (c) 2013 Apontador + Copyright (c) 2012 Airbnb Permission is hereby granted, free of charge, to any person obtaining diff --git a/linters/SublimeLinter/SublimeLinter.sublime-settings b/linters/SublimeLinter/SublimeLinter.sublime-settings deleted file mode 100644 index 1e12f7c6bb..0000000000 --- a/linters/SublimeLinter/SublimeLinter.sublime-settings +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Airbnb JSHint settings for use with SublimeLinter and Sublime Text 2. - * - * 1. Install SublimeLinter at https://github.com/SublimeLinter/SublimeLinter - * 2. Open user preferences for the SublimeLinter package in Sublime Text 2 - * * For Mac OS X go to _Sublime Text 2_ > _Preferences_ > _Package Settings_ > _SublimeLinter_ > _Settings - User_ - * 3. Paste the contents of this file into your settings file - * 4. Save the settings file - * - * @version 0.3.0 - * @see https://github.com/SublimeLinter/SublimeLinter - * @see http://www.jshint.com/docs/ - */ -{ - "jshint_options": - { - /* - * ENVIRONMENTS - * ================= - */ - - // Define globals exposed by modern browsers. - "browser": true, - - // Define globals exposed by jQuery. - "jquery": true, - - // Define globals exposed by Node.js. - "node": true, - - /* - * ENFORCING OPTIONS - * ================= - */ - - // Force all variable names to use either camelCase style or UPPER_CASE - // with underscores. - "camelcase": true, - - // Prohibit use of == and != in favor of === and !==. - "eqeqeq": true, - - // Suppress warnings about == null comparisons. - "eqnull": true, - - // Enforce tab width of 2 spaces. - "indent": 2, - - // Prohibit use of a variable before it is defined. - "latedef": true, - - // Require capitalized names for constructor functions. - "newcap": true, - - // Enforce use of single quotation marks for strings. - "quotmark": "single", - - // Prohibit trailing whitespace. - "trailing": true, - - // Prohibit use of explicitly undeclared variables. - "undef": true, - - // Warn when variables are defined but never used. - "unused": true - } -} diff --git a/resources.md b/resources.md new file mode 100644 index 0000000000..026465e575 --- /dev/null +++ b/resources.md @@ -0,0 +1,49 @@ +Resources +========= + +Read This +--------- + + - [Annotated ECMAScript 5.1](http://es5.github.com/) + - [JavaScript Scoping and Hoisting](http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html) + +Other Styleguides +----------------- + + - [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/) + +Other Styles +------------ + + - [Naming this in nested functions](https://gist.github.com/4135065) - Christian Johansen + - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) + +Books +----- + + - [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford + - [JavaScript Patterns](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov + - [Pro JavaScript Design Patterns](http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz + - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders + - [Maintainable JavaScript](http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas + - [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 + +Blogs +----- + + - [DailyJS](http://dailyjs.com/) + - [JavaScript Weekly](http://javascriptweekly.com/) + - [JavaScript, JavaScript...](http://javascriptweblog.wordpress.com/) + - [Bocoup Weblog](http://weblog.bocoup.com/) + - [Adequately Good](http://www.adequatelygood.com/) + - [NCZOnline](http://www.nczonline.net/) + - [Perfection Kills](http://perfectionkills.com/) + - [Ben Alman](http://benalman.com/) + - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/) + - [Dustin Diaz](http://dustindiaz.com/) + - [nettuts](http://net.tutsplus.com/?s=javascript) +