├── README.md └── linters └── jshintrc /README.md: -------------------------------------------------------------------------------- 1 | # Buffer JavaScript Style Guide 2 | 3 | *A work in progress inspired by [AirBnB's Style Guide](https://github.com/airbnb/javascript).* 4 | 5 | ## Goal 6 | 7 | To establish more consistency and readability across the Buffer team and our 8 | open source projects. 9 | 10 | ## Ideals 11 | 12 | > **Have a bias toward clarity** - from [The Buffer Values](http://www.slideshare.net/Bufferapp/buffer-culture-04) 13 | 14 | - We should always aim to write code that is clear and readable. 15 | - Use whitespace. Add comments liberally where needed, but strive to write code that's clear and self documenting 16 | - Always try to write code that clearly demonstrates and communicates it's intent. 17 | 18 | ## Table of Contents 19 | 20 | 1. [Naming Conventions](#naming-conventions) 21 | 2. [Variables](#variables) 22 | 3. [Strings](#strings) 23 | 4. [Blocks](#blocks) 24 | 5. [Whitespace](#whitespace) 25 | 6. [jQuery](#jquery) 26 | 7. [Scope & this](#scope--this) 27 | 28 | *Future sections may include: Commas+Semicolons, Comments, 29 | Conditional Expressions, Variables, Properties* 30 | 31 | ## Naming Conventions 32 | 33 | - Use camelCase variables and function names. use CAPS_UNDERSCORE for constants. 34 | 35 | ```javascript 36 | var updateText = 'Point Break is the best movie ever.'; 37 | 38 | function setUpdateText(arg) { //... 39 | 40 | // Constants 41 | var MAX_TWEET_LENGTH = 140; 42 | ``` 43 | 44 | - Use PascalCase or CapFirst when creating a constructor or extending a 45 | Backbone class. Avoid using a capital first letter unless it's one of these. 46 | 47 | ```javascript 48 | function Profile(service){ 49 | this.service = service; 50 | } 51 | 52 | var myProfile = new Profile('facebook'); 53 | 54 | var ProfileView = Backbone.View.extend({ 55 | events: {} 56 | }); 57 | ``` 58 | 59 | - Use a leading _ to denote private methods 60 | 61 | ```javascript 62 | MyClass.prototype._privateMethod = function(){ //... 63 | ``` 64 | 65 | - Be descriptive in the variables purpose. 66 | 67 | ```javascript 68 | var isFacebook = profile.get('service') === 'facebook'; 69 | // over... 70 | var facebook = profile.get('service') === 'facebook'; 71 | ``` 72 | 73 | ## Variables 74 | 75 | - Remember to use `var` to declare your variables and avoid poluting the global namespace. 76 | - Use one `var` declaration per line. Avoid re-use of a single `var` declaration. 77 | This helps keep our commits simple when adding removing a variable since we won't have 78 | to edit spacing or commas/semi-colons. 79 | 80 | ```javascript 81 | var open = false; 82 | var count = someCollection.length; 83 | ``` 84 | 85 | - Declare unassigned variables last. This helps keep organized and shows what will be assigned 86 | throughout a function. 87 | 88 | ```javascript 89 | // good :) 90 | var input = document.querySelectorAll('.js-my-input'); 91 | var text = input.value; 92 | var isOverLimit; 93 | 94 | if (profile.get('service') === 'twitter') { 95 | isOverLimit = text > 140; 96 | } 97 | 98 | if (isOverLimit) { 99 | // ... 100 | } 101 | 102 | // ...not great :( 103 | if (profile.get('service') === 'twitter') { 104 | var isOverLimit = text > 140; 105 | } 106 | 107 | // variable may be undefined here 108 | if (isOverLimit) { 109 | // ... 110 | } 111 | ``` 112 | 113 | - Assign variables at the top of functions. This avoids issues with hoisting and variable declaration 114 | 115 | ```javascript 116 | function myFunc($container) { 117 | var someBoolean = false; 118 | var isOpen; 119 | 120 | // ...other logic 121 | 122 | if (someBoolean === true) { 123 | isOpen = $container.hasClass('.open'); 124 | } 125 | 126 | // ...some more logic 127 | } 128 | ``` 129 | 130 | 131 | ## Strings 132 | 133 | - Use single quotes `''` over double quotes for strings. 134 | 135 | ```javascript 136 | var update = 'Some text'; 137 | ``` 138 | 139 | - Strings longer than 80 characters should be written across multiple lines 140 | using string concatenation. Use `+` for concatenation, avoid escaping EOLs 141 | with `\`. 142 | 143 | ```javascript 144 | var update = 'Grounds, half and half, affogato sit medium, decaffeinated ' + 145 | 'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ' + 146 | 'robusta barista, seasonal robust, mazagran qui blue mountain organic ' + 147 | 'breve arabica.'; 148 | 149 | // or use Array#join 150 | var update = [ 151 | 'Grounds, half and half, affogato sit medium, decaffeinated ', 152 | 'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ', 153 | 'robusta barista, seasonal robust, mazagran qui blue mountain organic ', 154 | 'breve arabica.' 155 | ].join(''); 156 | ``` 157 | 158 | ## Blocks 159 | 160 | - Use curlys `{}` for multi-line blocks, add spacing around statements to 161 | encourage readability. 162 | 163 | ```javascript 164 | if ( update.get('text').length < 140 ) { 165 | update.save(); 166 | } else { 167 | $('.js-warning').show(); 168 | } 169 | 170 | // It's ok to drop the braces if it's a short one-liner, try to keep it 171 | // under ~80 characters long so it's readable 172 | if ( update.get('text') > 140 ) this.showLengthWarning(); 173 | 174 | ``` 175 | 176 | ## Whitespace 177 | 178 | - Use soft tabs set to **2** spaces. 179 | 180 | ```javascript 181 | function isAwesome() { 182 | ∙∙return this.plan === 'awesome'; 183 | } 184 | this.getDataForModel(123) 185 | ∙∙.then(this.renderTemplate); 186 | 187 | // instead of 188 | function isBusiness() { 189 | ∙∙∙∙return ['small', 'business', 'agency'].indexOf(this.plan) > -1; 190 | } 191 | this.getDataForModel(456) 192 | .then(this.renderTemplate); 193 | ``` 194 | 195 | - Use whitespace with operators 196 | 197 | ```javascript 198 | var count = x + 2; 199 | // instead of 200 | var count=x+2; 201 | ``` 202 | 203 | - Use indentation for longer method chaining 204 | 205 | ```javascript 206 | $update 207 | .text(newText) 208 | .removeClass('editing') 209 | .addClass('saved'); 210 | 211 | // Instead of 212 | $update.text(newText).removeClass('editing').addClass('saved'); 213 | ``` 214 | 215 | ## jQuery 216 | 217 | - Use `.js-` prefixed class selectors. This prevents confusion between 218 | classes needed for design and ones used to reference the DOM from js. 219 | 220 | ```html 221 |