https://github.com/bufferapp/javascript-style-guide
Buffer's JavaScript style guide
https://github.com/bufferapp/javascript-style-guide
Last synced: 11 months ago
JSON representation
Buffer's JavaScript style guide
- Host: GitHub
- URL: https://github.com/bufferapp/javascript-style-guide
- Owner: bufferapp
- Created: 2014-06-06T02:32:23.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2015-01-19T18:41:50.000Z (about 11 years ago)
- Last Synced: 2025-01-01T09:09:34.110Z (about 1 year ago)
- Size: 316 KB
- Stars: 23
- Watchers: 41
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Buffer JavaScript Style Guide
*A work in progress inspired by [AirBnB's Style Guide](https://github.com/airbnb/javascript).*
## Goal
To establish more consistency and readability across the Buffer team and our
open source projects.
## Ideals
> **Have a bias toward clarity** - from [The Buffer Values](http://www.slideshare.net/Bufferapp/buffer-culture-04)
- We should always aim to write code that is clear and readable.
- Use whitespace. Add comments liberally where needed, but strive to write code that's clear and self documenting
- Always try to write code that clearly demonstrates and communicates it's intent.
## Table of Contents
1. [Naming Conventions](#naming-conventions)
2. [Variables](#variables)
3. [Strings](#strings)
4. [Blocks](#blocks)
5. [Whitespace](#whitespace)
6. [jQuery](#jquery)
7. [Scope & this](#scope--this)
*Future sections may include: Commas+Semicolons, Comments,
Conditional Expressions, Variables, Properties*
## Naming Conventions
- Use camelCase variables and function names. use CAPS_UNDERSCORE for constants.
```javascript
var updateText = 'Point Break is the best movie ever.';
function setUpdateText(arg) { //...
// Constants
var MAX_TWEET_LENGTH = 140;
```
- Use PascalCase or CapFirst when creating a constructor or extending a
Backbone class. Avoid using a capital first letter unless it's one of these.
```javascript
function Profile(service){
this.service = service;
}
var myProfile = new Profile('facebook');
var ProfileView = Backbone.View.extend({
events: {}
});
```
- Use a leading _ to denote private methods
```javascript
MyClass.prototype._privateMethod = function(){ //...
```
- Be descriptive in the variables purpose.
```javascript
var isFacebook = profile.get('service') === 'facebook';
// over...
var facebook = profile.get('service') === 'facebook';
```
## Variables
- Remember to use `var` to declare your variables and avoid poluting the global namespace.
- Use one `var` declaration per line. Avoid re-use of a single `var` declaration.
This helps keep our commits simple when adding removing a variable since we won't have
to edit spacing or commas/semi-colons.
```javascript
var open = false;
var count = someCollection.length;
```
- Declare unassigned variables last. This helps keep organized and shows what will be assigned
throughout a function.
```javascript
// good :)
var input = document.querySelectorAll('.js-my-input');
var text = input.value;
var isOverLimit;
if (profile.get('service') === 'twitter') {
isOverLimit = text > 140;
}
if (isOverLimit) {
// ...
}
// ...not great :(
if (profile.get('service') === 'twitter') {
var isOverLimit = text > 140;
}
// variable may be undefined here
if (isOverLimit) {
// ...
}
```
- Assign variables at the top of functions. This avoids issues with hoisting and variable declaration
```javascript
function myFunc($container) {
var someBoolean = false;
var isOpen;
// ...other logic
if (someBoolean === true) {
isOpen = $container.hasClass('.open');
}
// ...some more logic
}
```
## Strings
- Use single quotes `''` over double quotes for strings.
```javascript
var update = 'Some text';
```
- Strings longer than 80 characters should be written across multiple lines
using string concatenation. Use `+` for concatenation, avoid escaping EOLs
with `\`.
```javascript
var update = 'Grounds, half and half, affogato sit medium, decaffeinated ' +
'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ' +
'robusta barista, seasonal robust, mazagran qui blue mountain organic ' +
'breve arabica.';
// or use Array#join
var update = [
'Grounds, half and half, affogato sit medium, decaffeinated ',
'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ',
'robusta barista, seasonal robust, mazagran qui blue mountain organic ',
'breve arabica.'
].join('');
```
## Blocks
- Use curlys `{}` for multi-line blocks, add spacing around statements to
encourage readability.
```javascript
if ( update.get('text').length < 140 ) {
update.save();
} else {
$('.js-warning').show();
}
// It's ok to drop the braces if it's a short one-liner, try to keep it
// under ~80 characters long so it's readable
if ( update.get('text') > 140 ) this.showLengthWarning();
```
## Whitespace
- Use soft tabs set to **2** spaces.
```javascript
function isAwesome() {
∙∙return this.plan === 'awesome';
}
this.getDataForModel(123)
∙∙.then(this.renderTemplate);
// instead of
function isBusiness() {
∙∙∙∙return ['small', 'business', 'agency'].indexOf(this.plan) > -1;
}
this.getDataForModel(456)
.then(this.renderTemplate);
```
- Use whitespace with operators
```javascript
var count = x + 2;
// instead of
var count=x+2;
```
- Use indentation for longer method chaining
```javascript
$update
.text(newText)
.removeClass('editing')
.addClass('saved');
// Instead of
$update.text(newText).removeClass('editing').addClass('saved');
```
## jQuery
- Use `.js-` prefixed class selectors. This prevents confusion between
classes needed for design and ones used to reference the DOM from js.
```html
Some update text
```
```javascript
var $content = $('.js-update-content');
$content.text('New text');
```
- Prefix jQuery object variables with a `$`. This makes it easier to distingush jQuery variables vs other variables and DOM elements.
```javascript
var $sidebar = $('.js-sidebar');
```
- Cache jQuery lookups.
```javascript
// Use this...
var $sidebar = $('.js-sidebar');
$sidebar.addClass('hidden');
$sidebar.data('id', '1234');
// Instead of
$('.js-sidebar').addClass('hidden');
$('.js-sidebar').data('id', '1234');
```
- Use Promises with $.ajax. jQuery's docs use them as the new default. Use `.then` or `.always` over `.done` and `.fail`
```javascript
$.ajax({ url: '/updates.json' })
.then(function(data){
renderUpdates(data.updates);
}, function(){
alert('Request failed');
});
// Promises also work nicely for wrapping a more complex $.ajax request
function saveUpdateText(updateId, text) {
return $.ajax({
type: 'post'.
url: '/updates/' + updateId + '.json',
data: {
body: text
}
});
}
// The response
function showSuccessNotification(data) {
new Notification(data.message);
}
// Usage is very clean and easy to read
saveUpdateText(123, 'My new update text')
.then(showSuccessNotification);
```
## Scope & this
- Use `.bind(this)` to pass scope to functions if possible.
Use `var _this = this;` if it makes your code simpler and more readable.
```javascript
someMethod: function(data) {
this.saveMyUpdate(data)
.then(function(data){
this.collection.add(data);
this.showSavedNotification();
}.bind(this));
}
var myUpdates = updates.filter(function(update){
return update.type === this.getCurrentType();
}.bind(this));
// Using _this - Maybe this isn't the best example, but you get the idea :)
loadModelDataInForm: function(id){
var _this = this;
$.ajax({ url: '/model/' + id + '/' })
.then(function(data){
_this.renderTemplate(data);
$('.js-save-button').on('click', function(e){
$(this).text('Saving...');
_this
.getDataFromForm()
.save();
});
}, function(err){
alert(err);
});
}
```