• Stars
    star
    168
  • Rank 225,507 (Top 5 %)
  • Language
  • License
    MIT License
  • Created over 10 years ago
  • Updated over 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JavaScript Styleguide, can be applied to other things as well.

The Zen Approach

By Nijiko Yonskai - Revision 29

Table of Contents

  1. Foreword
  2. General Tips
  3. Whitespace
    1. Tabs and Spaces
    2. Line Length
    3. Code
      1. Assignment
      2. Functions
      3. Objects
      4. Arrays
  4. Semicolons
    1. The Rules of ASI
    2. Restrictive Productions
  5. Natives
  6. Primitives
    1. Simple
    2. Complex
  7. Objects
    1. Notation
  8. Arrays
    1. Cloning
  9. Strings
    1. Multiline
  10. Variables
  11. Other Styles
  12. TODO

===

Foreword

I'm no Zen Master.

I'm slowly learning how to be one however. In the beginning, I was rigid, like the trunk of a tree. Solid in my beliefs that what I did was the best; The only art in existence worth reading; Simplicity at it's finest; A styleguide for the ages was what my code was.

I've learned that thinking like this is extremely wrong on multiple levels.

Unlike me, JavaScript is more like the branches of the tree. It sways whatever way the wind blows. It goes with the flow; It does not really care how aesthetically pleasing you wish to make it. It gives you the flexibility that you need, and if you bend too far it breaks.

Being the trunk, you will always be underneath that flexibility. You have yet to understand and experience liberation. Even those branches are not liberated, the wind, that's the liberation you should strive for. The real flow. It doesn't even know the branches are there; but it moves them to it's will, not just this tree but any tree.

Becoming more like the wind, you must open your mind, cast aside any bias towards the black and white your mind controls you under and realize code more for it's ability to work, be performant, and at best consistent rather than how it appears.

Not only will you learn more, you'll be able to read the most difficult patterns; compact code; and begin experimenting, creating your own style, styleguide, and then finally realizing it's all bullshit and in a year or two what you like now will completely change.

===

After working so closely with this language, JavaScript, for so many years (going on twelve now) these are some of my findings. Some items ramble on, others have concise points. Keep an open mind, and if you find something at fault; Please, open an issue. Thank you.

===

General Tips

  1. Avoid things that are inherently bad, or cause performance problems.
  2. Find inspiration in the differences you have.
  3. Learn from your mistakes, however small or big, admit them; It's okay, we all make them.
  4. If it does not affect performance, obscures maintainability, or does not affect the outcome, it is aesthetic. It cannot be right or wrong.

Whitespace

Balance between code and space, offers much insight, however through many battles do we gain any knowledge.

Tabs and Spaces

Ah. The age old argument.

  1. Use what everyone else in your group is using.
  2. If you are the only one, try out spaces.

Why not tabs?

Tabs can be problematic when switching between environments, and different computers. This is also a benefit for them in some cases like large groups where many people have differing ideals and prefer different widths than others. Tabs can be set to a variable width in most editors making it very useful.

This feature though, can be a double-edged sword; What was once useful, when viewing code on a site such as github, you will always see the full tab width (4 spaces). Which can create confusion when those who do not use full tabs scan code in places other than their editor.

Spaces unlike tabs remain at a constant regardless of the system you put them on. Two spaces here will be two spaces everywhere.

Why not spaces?

Basically, the opposite of tabs. Being constant, this means if someone in your group prefers 3 space and you are using 2 space. Someone is going to lose the argument, and be a bit jaded. Granted, whoever is joining the group, should just follow the rules above to avoid argument.

Line Length

A man once told me a page, on this page he said, stay within your editor viewport.

  1. For man pages, a good length is somewhere around 60 ~ 80.
  2. For all other things, word-wrap exists.

Code

The final frontier, where many come to put stake, and many rest in peace.

Assignment

Even spaces, one space after var or let, one space after the assignment, no space before the final semicolon.

var hello = "world";

Functions

One space before parens (()) and before the brace ({).

function noop (args, spaced, normally) {
  // Code goes here
}

This is for a few reasons, it's not because of preference:

  1. Syntax Highlighters. Some highlighters and themes will only highlight arguments correctly under these conditions.
  2. Consistency. You put a space after function, continue with the rest of the syntax.

Objects

One space after the property notation ("property":)

var example = {
  "property": 'one'
};

Arrays

Up to you, never had any preference here.

I generally just make sure the comma is attached to the previous item:

var example = [1, 2, "three"];

Semicolons

Most likely the second largest debate, if not the largest, surrounding JavaScript / EcmaScript. There is the dark side, the one who purpetuates lies and fear, spreading illusion; evils; and fallacies regarding semicolon requirement. Then there is the good side, the one who spreads the facts; quotes the ASI rules; and provides a deeper, higher if you will, understanding of the JavaScript language.

For a moment, walk with me, on the side of evil and good. As we explore those rules, so you can decide for yourself, whether you would like to live a life where you live a worry free life and use semicolons, or you live a life of understanding and worry free not using semicolons.

How... can both sides... be worry free? Come with me my child, I shall tell you... nay, I shall show you.

The Rules of ASI

What is ASI? Automatic Semicolon Insertion. The true bearer of bad news for poorly written statements. However if you follow the rules, you will not be judged harshly by its standards.

Statement is terminated by \n unless:

  1. Open-ended assignments - The statement has an unclosed syntax character (), ], and }), or ends in a way it usually does not, e.g. ending in (., or ,).
  2. Open-ended blocks - It's a for, if, else, do, or while statement without an opening brace ({).
  3. Operator openings - The next line begins with a special character (., ,, *, +, -, /, ?, :, [, () or another operator (e.g. binary operators) that is found between two tokens in a single expression.

The judge is not so strict, but there are many cases where you can falter. So let's explore them further.

Open-ended Assignments

In many cases you've encountered these and typed them a thousand times when doing Object Literals, Arrays, or ternary statements wrapped in parens (more on why there is this distinction here later).

// this is not ended, and (should) throw an error.
var errors, message = (
  errors ? "I forsee problems in your life." : "Everything is as clear as the blue sky"
),

// this however ends and should not throw an error.
var errors, message = (
  errors ? "I forsee problems in your life." : "Everything is as clear as the blue sky"
)

These are at the core the basics, of javascript. Let us continue onward.

Open-ended blocks

These are regarded as one of the major annoyances, and praised as one the best features. Statements without braces.

function check_authentication (user, callback) {
  if (typeof user === 'function') 
    callback = user, 
    user = false;
  
  callback(!!user);
}

Here, unlike the function statement, the if statement does not require braces, not only that we can do multiple assignments using the comma just as you could if you were instantianting them as variables.

Following the rules, the following would be legal:

function check_authentication (user, callback) {
  if (typeof user === 'function') 
    callback = user, 
    user = false
  
  callback(!!user)
}

The if statement will not have a semicolon inserted (if (x)\ny() is the same as if (x) { y() }), and following the previous rule, the callback assignment line will not have a semicolon inserted; Only the user line, and eventually the callback invoke line.

Operator openings

Lines that begin with an operator of some sort following a line that should have been terminated will cause the insertion to continue without inserting a semicolon.

Here is an example:

var error = false

var message = error
  ? "I forsee problems in your life." 
  : "Everything is as clear as the blue sky"

Remember earlier when I stated that I would go further into detail as to why parens mattered on ternary statements regarding that rule? Well this rule will allow you to omit the parens and multiline ternary statements without fear of early termination.

As a fair note, these openings will always regard the next token, not the prior. So things such as i\n++\nj can lead to problems as it will be interpreted as:

i;
++j;

Another edge case is when you invoke a method or function and immediately after use an operator without placing a semicolon before it or on the ending of your method which will cause the interpreter to continue and cause your code to break.

methods()
[1,2,3].forEach()

// interprets as
methods()[1,2,3].forEach();

To avoid this you can do a few things:

// use semicolons
methods();
[1,2,3].forEach();

// use a single semicolon before the operator
methods()
;[1,2,3].forEach()

// the cleaner way is assignment, should you not want semicolons
var arr = [1,2,3]
methods()
arr.forEach()

Restrictive Productions

Restrictive productions will immediately add a newline after the following statements break, return, throw, continue, or postfix operators such as -- and ++. Thus doing things like this:

return
       7

Causes problems, a better example is a for inside of a while statement where you attempt to break the outer statement and you newlined the method name causing not the outer to break but the inner. Read more about this here.

Decisions

So, now that you have learned, or hopefully have learned the rules, and certain scenarios that can trip you up, or give you headaches, it's up to you to decide your path. Take some time trying out both, write a few projects without semicolons, and a few with; See what you like more.

Remember, when you are in a group, house rules ettiquete please.

Natives

Do not extend them, in the end you will only find trouble. This path is narrow and crumbles beneath the feet quickly. Use caution when treading.

  • I myself, many times before, have done this. I've learned from my mistakes that not everyone follows the age old rule of checking hasOwnProperty this is one of the biggest reasons you shouldn't do it.

Only invoke using Natives when you are building the following as they can only provide benefits in these situations:

  1. Class Systems
  2. Modular Extensions
  3. Game Engines (Beware of Array in this situation for performance)
  4. Complex Problems. (Think algorithms, machine learning, ai, modeling)

Primitives

Two types, simple and complex.

Simple

Direct access.

  1. String
  2. Number
  3. Boolean
  4. null
  5. undefined
var one = 1;
var two = one;

two = 2;

console.log(one, two); // 1, 2

Complex

Reference access.

  1. Array
  2. Object
  3. Function
var one = [1, 2];
var two = one;

two[0] = 2;

console.log(one[0], one[1]); // (2, 2)

This can help you and be your worst enemy in certain situations.

To understand more about why this happens read about allocation, pointers, and etc in other languages such as Java, C++, C, C# to get a notion of what is going on.

Objects

Always remember: No trailing commas, for objects, this can break IE8 and earlier engines, also should you wish to port it to JSON it is not compatible.

If the thing you are building is not one of those above under the Natives list and is performance related, use {} over Object.

var example = {
  "one": 1,
  "two": 2
};

console.log(example.one);

Side note, by encapsulating your properties with quotations you will avoid headaches should you require properties with special characters in the future. However modern editors will allow you to easily cure this using multi-line editing.

Notation

Use Bracket Notation:

  1. When using a variable.
  2. When properties have spaces, or characters that are not allowed in dot notation.
  3. When properties are reserved.

Use Dot Notation

  1. In all other situations.

Using reserved words

If you use reserved words on objects and attempt to access them through dot notation, your code will not work in older versions of IE.

// Will break in older browsers such as IE
var example = {
  new: function () {}
};

example.new;

// Will work in older browsers.
// Acceptable, in my opinion only for the three situations I mentioned earlier.
var example = {
  "new": function () {}
};

example['new'];

Arrays

Always remember: Trailing commas can lead to larger arrays than you expect, unless you are purposely requiring a longer length, don't use trailing commas.

If the thing you are building is not one of those above under the Natives list and is performance related, use [] over Array.

Should you need to tell the future, a pre-defined length, use Array.

var example = ['one', 'two'];

console.log(example[0]);

Prefer native methods over complicated code. Such as .push, .pop, .splice, .sort, .filter, .map (where available; node.js), and .slice.

Cloning

Use .slice over iteration.

Strings

Use '' or "" dependant on situation, just attempt to be consistent.

  1. As a rule of thumb, generally I tend to use "" when I know it may be long bodies of text or is some sort of free-form string without regulations. Because it can contain ' more likely than ".
var slug = 'joe_biden'; // Slugs are restrictive, personally to be consistent, here I would use double quotes. It's just an example and you can still easily read / change it.
var name = "Joe Biden"; // Names can contain '
var biography = "Wouldn't it make more sense to be logical, and rational rather than precise and perfect? Nothing is perfect. I make mistakes, I'm human. I am Joe Biden.";

Multiline

This section is dependant on what you are building. If you are building something that requires high performance (game engines, or code that will see high throughput) and do not manipulate the dom I would suggest you not use [].join unless you are targeting IE7 and below. It's not bad, it's just not as performant as other ways.

If you are appending to the dom [].join happens to be the most performant and here are some tests to back this up.

The two fastest methods of multiline are one-line strings (no breaks), and in second using the \ character (breaks), with + (concat) trailing slightly behind. I'll let browser testing data back me up on this. (Note that this is done for JIT concurrently compiled code, not optimized code.)

My personal preference is to use one line for performance (word-wrap exists people), and then [].join for code that doesn't need to be performant, especially when it comes to including variables, it's just a lot cleaner. Should the line require variables and need to be performant I will use + concat notation. Unless I am doing DOM manipulation, in which case I use [].join.

var preferences = "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 not_likely = "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 more_likely = "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.";

Variables

Always declare variables using var. Otherwise you're going to make a global, and pollute the namespace.

var one = 1;
var two = "two";
var three =  1 * 3;
var four = function four () {
  return three + one;
};

Personally, I don't care how you set variables, the only rule of thumb I keep is the following:

  1. Assigned first, un-assigned last.

After years of trying to find the perfect style, I returned back to using multiple var statements for assigned variables, and multi-line for unassigned.

Why? Simple reason: Nesting & Heirarchy. The code flows, easy to scan and read without losing context of where I am. Blocks that follow begin on the same line as the last variable.

It looks like this:

var one = 1;
var two = 2;
var three = 3;
var four, five, six;

Looking at it now, I sort of feel like changing this and going to multiple var statements for un-assigned as well.

var one = 1;
var two = 2;
var three = 3;
var four;
var five;
var six;

Why? Because, it would make it easier in the future should I remove assignment later and wish for it to be at the start of my block with minimal code change; That's the only reason, it doesn't have to do with aesthetics, or anything like how it looks.

Should I know that those assignments will always happen later, I do single line, should I think they could change (meaning I am unsure about the future) I do multi-line.

This only applies in my preference to un-assigned.

Other Styles

The first, commonly used, tends to be hard to read and scan when you view it inside of code contextually; Without context it looks alright. The gap between the line-numbers, and the variable can cause visual problems for scanning when code comes immediately after starting on the same vertical rhythm that var is on. Nesting and heirarchy get lost.

// Single var statement, multiple variables, comma after, columnized.
// Loss of vertical rhythm.

var one = 1,
    two = 2,
    three = 3,
    four, 
    five, 
    six;

The next example, more commonly used in two-space code, while being cleaner and slightly easier to read provides new problems. Linting, and older engines may insert semicolons or check for trailing commas, which will throw errors here. Not only that, you still lose your vertical rhythm when viewing this block inside of code contextually.

I myself enjoyed this block for a year or two, now I avoid it like the plague.

// Single var statement, multiple variables, comma before.
// Can cause problems in some situations.
// Loss of vertical rhythm.

var one = 1
  , two = 2
  , three = 3
  , four
  , five
  , six;

There is also the single line, this is just hard to read after a certain point so I will skip it. Nobody really uses it, if used, should only be for short un-assigned lists.

Todo

Things I have not glossed over, yet here are some quick snippets of information you may find useful right away.

  1. Naming conventions. (Personally +1 for snake, camel, and pascal, also going over leading $ vs _ and when to use them.)
  2. Private variables. (Personally prefer real private variables over cheap hacks such as leading underscore.)
  3. Casting and Coercion. (It's pretty cool, fun, and many people don't know it exists.)
  4. Comments. (Personal Findings: Doc-blocks are cool for generation, single line are great for annotation, amazing code doesn't need much inline comments.)
  5. Blocks (Don't create variables inside blocks as a general rule of thumb, unless performance. Generally, using braces multi-line style is easier to read. Sometimes it's acceptable to ignore them.)
  6. Functions (When to var, when not to var. Always name them for logging sake.)
  7. Engines / Compilers (There are many different ones, v8, rhino, etc.. They don't always interpret the same and they have many different modes: concurrent vs optimized)

More Repositories

1

generate-schema

🧞 Convert JSON Objects to MySQL, JSON Schema, Mongoose, Google BigQuery, Swagger, and more.
JavaScript
1,026
star
2

minami

💅 Clean and minimal JSDoc 3 Template / Theme
JavaScript
573
star
3

file-size

📂 Lightweight filesize to human-readable / proportions w/o dependencies for node.js & browsers.
JavaScript
233
star
4

Validator

JSON Schema validation library for Javascript / Node / Express.
JavaScript
159
star
5

WinScreeny

Windows Screenfetch - Remember that linux only one? Not anymore.
Shell
86
star
6

Geometry.js

Javascript Geometry Class for Games / Etc
JavaScript
82
star
7

clarity

Clarity theme for Gitbook designed for The Zen Approach
CSS
74
star
8

http-responses

Node.js Middleware for standardizing the way you send HTTP response statuses.
JavaScript
46
star
9

Hasher

Javascript URL Hash Routing Made Simple.
JavaScript
45
star
10

fluf

A Fast, Minimalistic, Micro Routing / Web Application Framework for PHP5; Modeled after Sinatra.
PHP
40
star
11

breeze

Javascript async flow control manager
JavaScript
39
star
12

Diacritics.js

Diacritic javascript module for cleaning or stripping a string of accents and replacing them with an equivalent.
JavaScript
31
star
13

query-js

Query parser using native javascript, with caching on both the decoder and parser.
JavaScript
28
star
14

stripe-mock-webhooks

Node.js module for testing Stripe Webhooks, no internet required
JavaScript
25
star
15

Templator

JS Template Manager and Controller. Allows for external files, elements, and raw data, and supports over 9 template languages.
JavaScript
25
star
16

iConomy

Economy Java Plugin for hey0's Mod
Java
21
star
17

mithril-router

Django style router for Mithril.js
JavaScript
19
star
18

ukiyo

🏃‍♂️ Barebones Single Page Application Development Server in Nodejs
JavaScript
19
star
19

mithril-validator

Easily validate Mithril.js forms, models, and objects.
JavaScript
19
star
20

diffr

CLI diff tool for files, text, and JSON with human readable output.
JavaScript
17
star
21

General

General plugin for Bukkit
Java
16
star
22

sugarcube-starter

Easy to use starter kit for creating stories with Tweego, Twine and SugarCube.
JavaScript
15
star
23

Prevu

SublimeText -> Browser Preview
Python
15
star
24

stripe-mock-data

Node.js Stripe webhook & object data for mocking / testing purposes.
JavaScript
14
star
25

careful

Validate git branches according to git-flow before you push / commit code.
JavaScript
13
star
26

fantasy-ui

Clean, flat dark ui for Atom.
CSS
12
star
27

array-to-table

Convert an array of objects to a simple markdown table.
JavaScript
12
star
28

NinkoBB

Small, Flexible, and Powerful Open source Forum Script.
PHP
12
star
29

drink

Terminal Application Helper. Keep sessions alive, process input data, or output data. Go ahead, take a sip.
CoffeeScript
12
star
30

Permissions

Java
11
star
31

dotfiles

📁 Make Dotfiles Great Again 📁
Vim Script
10
star
32

ractive.sortable.js

Ractive sortable event definition
JavaScript
9
star
33

ractive.drag.drop.js

Native HTML5 Drag N' Drop ractive event definition.
JavaScript
9
star
34

telepath

Dark theme for CIRC (Chrome IRC)
CSS
8
star
35

.todo

@todo a human-readable .todo language & syntax. Watch/Fork this project!
JavaScript
8
star
36

mithril-tour-component

Tour Guide Component for Mithril.js
JavaScript
7
star
37

Markdown

Markdown for PHP
PHP
7
star
38

n0p3

You probably shouldn't use this Node.js module ever
JavaScript
7
star
39

NASA

Thin #Javascript wrappers for #HTML5 #API.
JavaScript
7
star
40

dollars-to-cents

Convert USD Dollars (formatted string, non-formatted, numerical value) to USD Cents (numerical).
JavaScript
7
star
41

WarpGates

WarpGates for Bukkit - Portal through time and blackholes!
Java
7
star
42

iConomy3

Please, if you fork iConomy only do so if you are really fixing or adding something useful!
Java
7
star
43

Estro

Extended String Object for JavaScript
JavaScript
6
star
44

butisitwebscale.com

Just pure science and mathematics to determine whether technologies are webscale
CSS
6
star
45

nasa-keypath

New Age Keypath Traversal Technology.
JavaScript
6
star
46

todo-tmbundle

@todo Textmate Syntax Highlighting, Works in Sublime Text / E as well.
5
star
47

nuuid

Not (another) unique universal identifier... But, it is. Faster and less prone to collisions than uuid as the scheme is ever changing, yet forever stable.
JavaScript
5
star
48

java.php

Java ported to PHP OOP
PHP
5
star
49

mithril-requests

Add sugar HTTP methods to Mithril.js
JavaScript
5
star
50

raygun-winston

Raygun transport for NodeJS Winston logging library
JavaScript
5
star
51

bacon.css

Bacon CSS. Delicious Syntax. Let's Get Sizzlin' - Check the link below for an example!
JavaScript
4
star
52

MiniJS

Better looking MicroJS
4
star
53

SimpleShop

Java
4
star
54

utils.js

Javascript Utilities, Snippets, and Knowledge Base
JavaScript
4
star
55

MiniDB

Tiny FlatFile Database
Java
4
star
56

mithril-component

React style components for mithril, easy and simple to use.
JavaScript
4
star
57

Cleaner

Java
3
star
58

electron-vue-starter

🌱 Base starter for Electron 6 / Vue 2.6 with Vue Router, Vuex, and more!
JavaScript
3
star
59

Tipper

Java
3
star
60

juttles

Commonly used / made Javascript / CoffeeScript utilities.
3
star
61

Transparent-Grid

A responsive grid system that works for fixed and fluid layouts written in stylus.
3
star
62

iChat

Java
3
star
63

havoc

Havoc Game Framework (originally god.js)
JavaScript
2
star
64

docker-ubuntu-image

Docker Base Image for Rapid Developer Environments
Shell
2
star
65

CommandCost

Example iConomy Addon Plugin
Java
2
star
66

napkin-bar

Design Patterns & Articles to help build a scalable Javascript application.
2
star
67

kong-plugin-prometheus

Kong plugin that enables an endpoint for Prometheus to access and obtain Kong metrics
Lua
2
star
68

lua-find

Javascript implementation of Lua's String.find functionality
JavaScript
2
star
69

mChat

mChat - Chat Formatting Plugin
Java
1
star
70

NiiGen

Python Psuedo-Random Password/Key Gen
Python
1
star
71

electron-react-starter

🌱 Base starter for Electron 7.x with React 16.x
JavaScript
1
star
72

ls_editsuite

A "web interface" to do stuff with LocalShops shops... currently supports V3
PHP
1
star
73

Reserves

Reserve list for Bukkit
1
star
74

Glonick

Java
1
star
75

Heirarchy

Permissions Configuration Language - HARC
Java
1
star
76

Bukget-Plugin

Bukkit bukget Plugin.
Java
1
star
77

nodoc

Easy, Simplified, Documentation Syntax Block Proposal for the JavaScript Language
1
star
78

SignTrader

Java
1
star
79

chariot

Chariot is a aggregated package manager, currently supports npm, and bower.
Shell
1
star
80

iAuction

iConomy Auctions
1
star