├── README.md
├── linters
├── SublimeLinter
│ └── SublimeLinter.sublime-settings
└── jshintrc
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Academy's JavaScript Style Guide() {
2 |
3 | A mostly reasonable approach to JavaScript, *Adapted from AirBnB's popular JavaScript style guide*.
4 |
5 |
6 | ## Table of Contents
7 |
8 | 1. [Types](#types)
9 | 1. [Objects](#objects)
10 | 1. [Arrays](#arrays)
11 | 1. [Strings](#strings)
12 | 1. [Functions](#functions)
13 | 1. [Properties](#properties)
14 | 1. [Variables](#variables)
15 | 1. [Hoisting](#hoisting)
16 | 1. [Conditional Expressions & Equality](#conditional-expressions--equality)
17 | 1. [Blocks](#blocks)
18 | 1. [Comments](#comments)
19 | 1. [Whitespace](#whitespace)
20 | 1. [Commas](#commas)
21 | 1. [Semicolons](#semicolons)
22 | 1. [Type Casting & Coercion](#type-casting--coercion)
23 | 1. [Naming Conventions](#naming-conventions)
24 | 1. [Accessors](#accessors)
25 | 1. [Constructors](#constructors)
26 | 1. [Events](#events)
27 | 1. [Modules](#modules)
28 | 1. [jQuery](#jquery)
29 | 1. [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
30 | 1. [Testing](#testing)
31 | 1. [Performance](#performance)
32 | 1. [Resources](#resources)
33 | 1. [In the Wild](#in-the-wild)
34 | 1. [Translation](#translation)
35 | 1. [The JavaScript Style Guide Guide](#the-javascript-style-guide-guide)
36 | 1. [Contributors](#contributors)
37 | 1. [License](#license)
38 |
39 | ## Types
40 |
41 | - **Primitives**: When you access a primitive type you work directly on its value
42 |
43 | + `string`
44 | + `number`
45 | + `boolean`
46 | + `null`
47 | + `undefined`
48 |
49 | ```javascript
50 | var foo = 1,
51 | bar = foo;
52 |
53 | bar = 9;
54 |
55 | console.log(foo, bar); // => 1, 9
56 | ```
57 | - **Complex**: When you access a complex type you work on a reference to its value
58 |
59 | + `object`
60 | + `array`
61 | + `function`
62 |
63 | ```javascript
64 | var foo = [1, 2],
65 | bar = foo;
66 |
67 | bar[0] = 9;
68 |
69 | console.log(foo[0], bar[0]); // => 9, 9
70 | ```
71 |
72 | **[⬆ back to top](#table-of-contents)**
73 |
74 | ## Objects
75 |
76 | - Use the literal syntax for object creation.
77 |
78 | ```javascript
79 | // bad
80 | var item = new Object();
81 |
82 | // good
83 | var item = {};
84 | ```
85 |
86 | - 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)
87 |
88 | ```javascript
89 | // bad
90 | var superman = {
91 | default: { clark: 'kent' },
92 | private: true
93 | };
94 |
95 | // good
96 | var superman = {
97 | defaults: { clark: 'kent' },
98 | hidden: true
99 | };
100 | ```
101 |
102 | - Use readable synonyms in place of reserved words.
103 |
104 | ```javascript
105 | // bad
106 | var superman = {
107 | class: 'alien'
108 | };
109 |
110 | // bad
111 | var superman = {
112 | klass: 'alien'
113 | };
114 |
115 | // good
116 | var superman = {
117 | type: 'alien'
118 | };
119 | ```
120 |
121 | **[⬆ back to top](#table-of-contents)**
122 |
123 | ## Arrays
124 |
125 | - Use the literal syntax for array creation
126 |
127 | ```javascript
128 | // bad
129 | var items = new Array();
130 |
131 | // good
132 | var items = [];
133 | ```
134 |
135 | - If you don't know array length use Array#push.
136 |
137 | ```javascript
138 | var someStack = [];
139 |
140 |
141 | // bad
142 | someStack[someStack.length] = 'abracadabra';
143 |
144 | // good
145 | someStack.push('abracadabra');
146 | ```
147 |
148 | - When you need to copy an array use Array#slice. [jsPerf](http://jsperf.com/converting-arguments-to-an-array/7)
149 |
150 | ```javascript
151 | var len = items.length,
152 | itemsCopy = [],
153 | i;
154 |
155 | // bad
156 | for (i = 0; i < len; i++) {
157 | itemsCopy[i] = items[i];
158 | }
159 |
160 | // good
161 | itemsCopy = items.slice();
162 | ```
163 |
164 | - To convert an array-like object to an array, use Array#slice.
165 |
166 | ```javascript
167 | function trigger() {
168 | var args = Array.prototype.slice.call(arguments);
169 | ...
170 | }
171 | ```
172 |
173 | **[⬆ back to top](#table-of-contents)**
174 |
175 |
176 | ## Strings
177 |
178 | - Use single quotes `''` for strings
179 |
180 | ```javascript
181 | // bad
182 | var name = "Bob Parr";
183 |
184 | // good
185 | var name = 'Bob Parr';
186 |
187 | // bad
188 | var fullName = "Bob " + this.lastName;
189 |
190 | // good
191 | var fullName = 'Bob ' + this.lastName;
192 | ```
193 |
194 | - Strings longer than 80 characters should be written across multiple lines using string concatenation.
195 | - 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)
196 |
197 | ```javascript
198 | // bad
199 | 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.';
200 |
201 | // bad
202 | var errorMessage = 'This is a super long error that was thrown because \
203 | of Batman. When you stop to think about how Batman had anything to do \
204 | with this, you would get nowhere \
205 | fast.';
206 |
207 | // good
208 | var errorMessage = 'This is a super long error that was thrown because ' +
209 | 'of Batman. When you stop to think about how Batman had anything to do ' +
210 | 'with this, you would get nowhere fast.';
211 | ```
212 |
213 | - When programmatically building up a string, use Array#join instead of string concatenation. Mostly for IE: [jsPerf](http://jsperf.com/string-vs-array-concat/2).
214 |
215 | ```javascript
216 | var items,
217 | messages,
218 | length,
219 | i;
220 |
221 | messages = [{
222 | state: 'success',
223 | message: 'This one worked.'
224 | }, {
225 | state: 'success',
226 | message: 'This one worked as well.'
227 | }, {
228 | state: 'error',
229 | message: 'This one did not work.'
230 | }];
231 |
232 | length = messages.length;
233 |
234 | // bad
235 | function inbox(messages) {
236 | items = '
';
237 |
238 | for (i = 0; i < length; i++) {
239 | items += '- ' + messages[i].message + '
';
240 | }
241 |
242 | return items + '
';
243 | }
244 |
245 | // good
246 | function inbox(messages) {
247 | items = [];
248 |
249 | for (i = 0; i < length; i++) {
250 | items[i] = messages[i].message;
251 | }
252 |
253 | return '';
254 | }
255 | ```
256 |
257 | **[⬆ back to top](#table-of-contents)**
258 |
259 |
260 | ## Functions
261 |
262 | - Function expressions:
263 |
264 | ```javascript
265 | // anonymous function expression
266 | var anonymous = function() {
267 | return true;
268 | };
269 |
270 | // named function expression
271 | var named = function named() {
272 | return true;
273 | };
274 |
275 | // immediately-invoked function expression (IIFE)
276 | (function() {
277 | console.log('Welcome to the Internet. Please follow me.');
278 | })();
279 | ```
280 |
281 | - 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.
282 | - **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).
283 |
284 | ```javascript
285 | // bad
286 | if (currentUser) {
287 | function test() {
288 | console.log('Nope.');
289 | }
290 | }
291 |
292 | // good
293 | var test;
294 | if (currentUser) {
295 | test = function test() {
296 | console.log('Yup.');
297 | };
298 | }
299 | ```
300 |
301 | - Never name a parameter `arguments`, this will take precedence over the `arguments` object that is given to every function scope.
302 |
303 | ```javascript
304 | // bad
305 | function nope(name, options, arguments) {
306 | // ...stuff...
307 | }
308 |
309 | // good
310 | function yup(name, options, args) {
311 | // ...stuff...
312 | }
313 | ```
314 |
315 | **[⬆ back to top](#table-of-contents)**
316 |
317 |
318 |
319 | ## Properties
320 |
321 | - Use dot notation when accessing properties.
322 |
323 | ```javascript
324 | var luke = {
325 | jedi: true,
326 | age: 28
327 | };
328 |
329 | // bad
330 | var isJedi = luke['jedi'];
331 |
332 | // good
333 | var isJedi = luke.jedi;
334 | ```
335 |
336 | - Use subscript notation `[]` when accessing properties with a variable.
337 |
338 | ```javascript
339 | var luke = {
340 | jedi: true,
341 | age: 28
342 | };
343 |
344 | function getProp(prop) {
345 | return luke[prop];
346 | }
347 |
348 | var isJedi = getProp('jedi');
349 | ```
350 |
351 | **[⬆ back to top](#table-of-contents)**
352 |
353 |
354 | ## Variables
355 |
356 | - 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.
357 |
358 | ```javascript
359 | // bad
360 | superPower = new SuperPower();
361 |
362 | // good
363 | var superPower = new SuperPower();
364 | ```
365 |
366 | - Use one `var` declaration for multiple variables and declare each variable on a newline.
367 |
368 | ```javascript
369 | // bad
370 | var items = getItems();
371 | var goSportsTeam = true;
372 | var dragonball = 'z';
373 |
374 | // good
375 | var items = getItems(),
376 | goSportsTeam = true,
377 | dragonball = 'z';
378 | ```
379 |
380 | - Declare unassigned variables last. This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables.
381 |
382 | ```javascript
383 | // bad
384 | var i, len, dragonball,
385 | items = getItems(),
386 | goSportsTeam = true;
387 |
388 | // bad
389 | var i, items = getItems(),
390 | dragonball,
391 | goSportsTeam = true,
392 | len;
393 |
394 | // good
395 | var items = getItems(),
396 | goSportsTeam = true,
397 | dragonball,
398 | length,
399 | i;
400 | ```
401 |
402 | - Assign variables at the top of their scope. This helps avoid issues with variable declaration and assignment hoisting related issues.
403 |
404 | ```javascript
405 | // bad
406 | function() {
407 | test();
408 | console.log('doing stuff..');
409 |
410 | //..other stuff..
411 |
412 | var name = getName();
413 |
414 | if (name === 'test') {
415 | return false;
416 | }
417 |
418 | return name;
419 | }
420 |
421 | // good
422 | function() {
423 | var name = getName();
424 |
425 | test();
426 | console.log('doing stuff..');
427 |
428 | //..other stuff..
429 |
430 | if (name === 'test') {
431 | return false;
432 | }
433 |
434 | return name;
435 | }
436 |
437 | // bad
438 | function() {
439 | var name = getName();
440 |
441 | if (!arguments.length) {
442 | return false;
443 | }
444 |
445 | return true;
446 | }
447 |
448 | // good
449 | function() {
450 | if (!arguments.length) {
451 | return false;
452 | }
453 |
454 | var name = getName();
455 |
456 | return true;
457 | }
458 | ```
459 |
460 | **[⬆ back to top](#table-of-contents)**
461 |
462 |
463 | ## Hoisting
464 |
465 | - Variable declarations get hoisted to the top of their scope, their assignment does not.
466 |
467 | ```javascript
468 | // we know this wouldn't work (assuming there
469 | // is no notDefined global variable)
470 | function example() {
471 | console.log(notDefined); // => throws a ReferenceError
472 | }
473 |
474 | // creating a variable declaration after you
475 | // reference the variable will work due to
476 | // variable hoisting. Note: the assignment
477 | // value of `true` is not hoisted.
478 | function example() {
479 | console.log(declaredButNotAssigned); // => undefined
480 | var declaredButNotAssigned = true;
481 | }
482 |
483 | // The interpreter is hoisting the variable
484 | // declaration to the top of the scope.
485 | // Which means our example could be rewritten as:
486 | function example() {
487 | var declaredButNotAssigned;
488 | console.log(declaredButNotAssigned); // => undefined
489 | declaredButNotAssigned = true;
490 | }
491 | ```
492 |
493 | - Anonymous function expressions hoist their variable name, but not the function assignment.
494 |
495 | ```javascript
496 | function example() {
497 | console.log(anonymous); // => undefined
498 |
499 | anonymous(); // => TypeError anonymous is not a function
500 |
501 | var anonymous = function() {
502 | console.log('anonymous function expression');
503 | };
504 | }
505 | ```
506 |
507 | - Named function expressions hoist the variable name, not the function name or the function body.
508 |
509 | ```javascript
510 | function example() {
511 | console.log(named); // => undefined
512 |
513 | named(); // => TypeError named is not a function
514 |
515 | superPower(); // => ReferenceError superPower is not defined
516 |
517 | var named = function superPower() {
518 | console.log('Flying');
519 | };
520 | }
521 |
522 | // the same is true when the function name
523 | // is the same as the variable name.
524 | function example() {
525 | console.log(named); // => undefined
526 |
527 | named(); // => TypeError named is not a function
528 |
529 | var named = function named() {
530 | console.log('named');
531 | }
532 | }
533 | ```
534 |
535 | - Function declarations hoist their name and the function body.
536 |
537 | ```javascript
538 | function example() {
539 | superPower(); // => Flying
540 |
541 | function superPower() {
542 | console.log('Flying');
543 | }
544 | }
545 | ```
546 |
547 | - 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/)
548 |
549 | **[⬆ back to top](#table-of-contents)**
550 |
551 |
552 |
553 | ## Conditional Expressions & Equality
554 |
555 | - Use `===` and `!==` over `==` and `!=`.
556 | - Conditional expressions are evaluated using coercion with the `ToBoolean` method and always follow these simple rules:
557 |
558 | + **Objects** evaluate to **true**
559 | + **Undefined** evaluates to **false**
560 | + **Null** evaluates to **false**
561 | + **Booleans** evaluate to **the value of the boolean**
562 | + **Numbers** evaluate to **false** if **+0, -0, or NaN**, otherwise **true**
563 | + **Strings** evaluate to **false** if an empty string `''`, otherwise **true**
564 |
565 | ```javascript
566 | if ([0]) {
567 | // true
568 | // An array is an object, objects evaluate to true
569 | }
570 | ```
571 |
572 | - Use shortcuts.
573 |
574 | ```javascript
575 | // bad
576 | if (name !== '') {
577 | // ...stuff...
578 | }
579 |
580 | // good
581 | if (name) {
582 | // ...stuff...
583 | }
584 |
585 | // bad
586 | if (collection.length > 0) {
587 | // ...stuff...
588 | }
589 |
590 | // good
591 | if (collection.length) {
592 | // ...stuff...
593 | }
594 | ```
595 |
596 | - For more information see [Truth Equality and JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll
597 |
598 | **[⬆ back to top](#table-of-contents)**
599 |
600 |
601 | ## Blocks
602 |
603 | - Use braces with all multi-line blocks.
604 |
605 | ```javascript
606 | // bad
607 | if (test)
608 | return false;
609 |
610 | // good
611 | if (test) return false;
612 |
613 | // good
614 | if (test) {
615 | return false;
616 | }
617 |
618 | // bad
619 | function() { return false; }
620 |
621 | // good
622 | function() {
623 | return false;
624 | }
625 | ```
626 |
627 | **[⬆ back to top](#table-of-contents)**
628 |
629 |
630 | ## Comments
631 |
632 | - Use `/** ... */` for multiline comments. Include a description, specify types and values for all parameters and return values.
633 |
634 | ```javascript
635 | // bad
636 | // make() returns a new element
637 | // based on the passed in tag name
638 | //
639 | // @param tag
640 | // @return element
641 | function make(tag) {
642 |
643 | // ...stuff...
644 |
645 | return element;
646 | }
647 |
648 | // good
649 | /**
650 | * make() returns a new element
651 | * based on the passed in tag name
652 | *
653 | * @param tag
654 | * @return element
655 | */
656 | function make(tag) {
657 |
658 | // ...stuff...
659 |
660 | return element;
661 | }
662 | ```
663 |
664 | - 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.
665 |
666 | ```javascript
667 | // bad
668 | var active = true; // is current tab
669 |
670 | // good
671 | // is current tab
672 | var active = true;
673 |
674 | // bad
675 | function getType() {
676 | console.log('fetching type...');
677 | // set the default type to 'no type'
678 | var type = this._type || 'no type';
679 |
680 | return type;
681 | }
682 |
683 | // good
684 | function getType() {
685 | console.log('fetching type...');
686 |
687 | // set the default type to 'no type'
688 | var type = this._type || 'no type';
689 |
690 | return type;
691 | }
692 | ```
693 |
694 | - 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`.
695 |
696 | - Use `// FIXME:` to annotate problems
697 |
698 | ```javascript
699 | function Calculator() {
700 |
701 | // FIXME: shouldn't use a global here
702 | total = 0;
703 |
704 | return this;
705 | }
706 | ```
707 |
708 | - Use `// TODO:` to annotate solutions to problems
709 |
710 | ```javascript
711 | function Calculator() {
712 |
713 | // TODO: total should be configurable by an options param
714 | this.total = 0;
715 |
716 | return this;
717 | }
718 | ```
719 |
720 | **[⬆ back to top](#table-of-contents)**
721 |
722 |
723 | ## Whitespace
724 |
725 | - Use soft tabs set to 2 spaces
726 |
727 | ```javascript
728 | // bad
729 | function() {
730 | ∙∙∙∙var name;
731 | }
732 |
733 | // bad
734 | function() {
735 | ∙var name;
736 | }
737 |
738 | // good
739 | function() {
740 | ∙∙var name;
741 | }
742 | ```
743 |
744 | - Place 1 space before the leading brace.
745 |
746 | ```javascript
747 | // bad
748 | function test(){
749 | console.log('test');
750 | }
751 |
752 | // good
753 | function test() {
754 | console.log('test');
755 | }
756 |
757 | // bad
758 | dog.set('attr',{
759 | age: '1 year',
760 | breed: 'Bernese Mountain Dog'
761 | });
762 |
763 | // good
764 | dog.set('attr', {
765 | age: '1 year',
766 | breed: 'Bernese Mountain Dog'
767 | });
768 | ```
769 |
770 | - Set off operators with spaces.
771 |
772 | ```javascript
773 | // bad
774 | var x=y+5;
775 |
776 | // good
777 | var x = y + 5;
778 | ```
779 |
780 | - End files with a single newline character.
781 |
782 | ```javascript
783 | // bad
784 | (function(global) {
785 | // ...stuff...
786 | })(this);
787 | ```
788 |
789 | ```javascript
790 | // bad
791 | (function(global) {
792 | // ...stuff...
793 | })(this);↵
794 | ↵
795 | ```
796 |
797 | ```javascript
798 | // good
799 | (function(global) {
800 | // ...stuff...
801 | })(this);↵
802 | ```
803 |
804 | - Use indentation when making long method chains.
805 |
806 | ```javascript
807 | // bad
808 | $('#items').find('.selected').highlight().end().find('.open').updateCount();
809 |
810 | // good
811 | $('#items')
812 | .find('.selected')
813 | .highlight()
814 | .end()
815 | .find('.open')
816 | .updateCount();
817 |
818 | // bad
819 | var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true)
820 | .attr('width', (radius + margin) * 2).append('svg:g')
821 | .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
822 | .call(tron.led);
823 |
824 | // good
825 | var leds = stage.selectAll('.led')
826 | .data(data)
827 | .enter().append('svg:svg')
828 | .class('led', true)
829 | .attr('width', (radius + margin) * 2)
830 | .append('svg:g')
831 | .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
832 | .call(tron.led);
833 | ```
834 |
835 | **[⬆ back to top](#table-of-contents)**
836 |
837 | ## Commas
838 |
839 | - Leading commas: **Nope.**
840 |
841 | ```javascript
842 | // bad
843 | var once
844 | , upon
845 | , aTime;
846 |
847 | // good
848 | var once,
849 | upon,
850 | aTime;
851 |
852 | // bad
853 | var hero = {
854 | firstName: 'Bob'
855 | , lastName: 'Parr'
856 | , heroName: 'Mr. Incredible'
857 | , superPower: 'strength'
858 | };
859 |
860 | // good
861 | var hero = {
862 | firstName: 'Bob',
863 | lastName: 'Parr',
864 | heroName: 'Mr. Incredible',
865 | superPower: 'strength'
866 | };
867 | ```
868 |
869 | - 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)):
870 |
871 | > 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.
872 |
873 | ```javascript
874 | // bad
875 | var hero = {
876 | firstName: 'Kevin',
877 | lastName: 'Flynn',
878 | };
879 |
880 | var heroes = [
881 | 'Batman',
882 | 'Superman',
883 | ];
884 |
885 | // good
886 | var hero = {
887 | firstName: 'Kevin',
888 | lastName: 'Flynn'
889 | };
890 |
891 | var heroes = [
892 | 'Batman',
893 | 'Superman'
894 | ];
895 | ```
896 |
897 | **[⬆ back to top](#table-of-contents)**
898 |
899 |
900 | ## Semicolons
901 |
902 | - **Yup.**
903 |
904 | ```javascript
905 | // bad
906 | (function() {
907 | var name = 'Skywalker'
908 | return name
909 | })()
910 |
911 | // good
912 | (function() {
913 | var name = 'Skywalker';
914 | return name;
915 | })();
916 |
917 | // good (guards against the function becoming an argument when two files with IIFEs are concatenated)
918 | ;(function() {
919 | var name = 'Skywalker';
920 | return name;
921 | })();
922 | ```
923 |
924 | [Read more](http://stackoverflow.com/a/7365214/1712802).
925 |
926 | **[⬆ back to top](#table-of-contents)**
927 |
928 |
929 | ## Type Casting & Coercion
930 |
931 | - Perform type coercion at the beginning of the statement.
932 | - Strings:
933 |
934 | ```javascript
935 | // => this.reviewScore = 9;
936 |
937 | // bad
938 | var totalScore = this.reviewScore + '';
939 |
940 | // good
941 | var totalScore = '' + this.reviewScore;
942 |
943 | // bad
944 | var totalScore = '' + this.reviewScore + ' total score';
945 |
946 | // good
947 | var totalScore = this.reviewScore + ' total score';
948 | ```
949 |
950 | - Use `parseInt` for Numbers and always with a radix for type casting.
951 |
952 | ```javascript
953 | var inputValue = '4';
954 |
955 | // bad
956 | var val = new Number(inputValue);
957 |
958 | // bad
959 | var val = +inputValue;
960 |
961 | // bad
962 | var val = inputValue >> 0;
963 |
964 | // bad
965 | var val = parseInt(inputValue);
966 |
967 | // good
968 | var val = Number(inputValue);
969 |
970 | // good
971 | var val = parseInt(inputValue, 10);
972 | ```
973 |
974 | - 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.
975 |
976 | ```javascript
977 | // good
978 | /**
979 | * parseInt was the reason my code was slow.
980 | * Bitshifting the String to coerce it to a
981 | * Number made it a lot faster.
982 | */
983 | var val = inputValue >> 0;
984 | ```
985 |
986 | - **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:
987 |
988 | ```javascript
989 | 2147483647 >> 0 //=> 2147483647
990 | 2147483648 >> 0 //=> -2147483648
991 | 2147483649 >> 0 //=> -2147483647
992 | ```
993 |
994 | - Booleans:
995 |
996 | ```javascript
997 | var age = 0;
998 |
999 | // bad
1000 | var hasAge = new Boolean(age);
1001 |
1002 | // good
1003 | var hasAge = Boolean(age);
1004 |
1005 | // good
1006 | var hasAge = !!age;
1007 | ```
1008 |
1009 | **[⬆ back to top](#table-of-contents)**
1010 |
1011 |
1012 | ## Naming Conventions
1013 |
1014 | - Avoid single letter names. Be descriptive with your naming.
1015 |
1016 | ```javascript
1017 | // bad
1018 | function q() {
1019 | // ...stuff...
1020 | }
1021 |
1022 | // good
1023 | function query() {
1024 | // ..stuff..
1025 | }
1026 | ```
1027 |
1028 | - Use camelCase when naming objects, functions, and instances
1029 |
1030 | ```javascript
1031 | // bad
1032 | var OBJEcttsssss = {};
1033 | var this_is_my_object = {};
1034 | function c() {}
1035 | var u = new user({
1036 | name: 'Bob Parr'
1037 | });
1038 |
1039 | // good
1040 | var thisIsMyObject = {};
1041 | function thisIsMyFunction() {}
1042 | var user = new User({
1043 | name: 'Bob Parr'
1044 | });
1045 | ```
1046 |
1047 | - Use PascalCase when naming constructors or classes
1048 |
1049 | ```javascript
1050 | // bad
1051 | function user(options) {
1052 | this.name = options.name;
1053 | }
1054 |
1055 | var bad = new user({
1056 | name: 'nope'
1057 | });
1058 |
1059 | // good
1060 | function User(options) {
1061 | this.name = options.name;
1062 | }
1063 |
1064 | var good = new User({
1065 | name: 'yup'
1066 | });
1067 | ```
1068 |
1069 | - Use a leading underscore `_` when naming private properties
1070 |
1071 | ```javascript
1072 | // bad
1073 | this.__firstName__ = 'Panda';
1074 | this.firstName_ = 'Panda';
1075 |
1076 | // good
1077 | this._firstName = 'Panda';
1078 | ```
1079 |
1080 | - When saving a reference to `this` use `_this`.
1081 |
1082 | ```javascript
1083 | // bad
1084 | function() {
1085 | var self = this;
1086 | return function() {
1087 | console.log(self);
1088 | };
1089 | }
1090 |
1091 | // bad
1092 | function() {
1093 | var that = this;
1094 | return function() {
1095 | console.log(that);
1096 | };
1097 | }
1098 |
1099 | // good
1100 | function() {
1101 | var _this = this;
1102 | return function() {
1103 | console.log(_this);
1104 | };
1105 | }
1106 | ```
1107 |
1108 | - Name your functions. This is helpful for stack traces.
1109 |
1110 | ```javascript
1111 | // bad
1112 | var log = function(msg) {
1113 | console.log(msg);
1114 | };
1115 |
1116 | // good
1117 | var log = function log(msg) {
1118 | console.log(msg);
1119 | };
1120 | ```
1121 |
1122 | - **Note:** IE8 and below exhibit some quirks with named function expressions. See [http://kangax.github.io/nfe/](http://kangax.github.io/nfe/) for more info.
1123 |
1124 | **[⬆ back to top](#table-of-contents)**
1125 |
1126 |
1127 | ## Accessors
1128 |
1129 | - Accessor functions for properties are not required
1130 | - If you do make accessor functions use getVal() and setVal('hello')
1131 |
1132 | ```javascript
1133 | // bad
1134 | dragon.age();
1135 |
1136 | // good
1137 | dragon.getAge();
1138 |
1139 | // bad
1140 | dragon.age(25);
1141 |
1142 | // good
1143 | dragon.setAge(25);
1144 | ```
1145 |
1146 | - If the property is a boolean, use isVal() or hasVal()
1147 |
1148 | ```javascript
1149 | // bad
1150 | if (!dragon.age()) {
1151 | return false;
1152 | }
1153 |
1154 | // good
1155 | if (!dragon.hasAge()) {
1156 | return false;
1157 | }
1158 | ```
1159 |
1160 | - It's okay to create get() and set() functions, but be consistent.
1161 |
1162 | ```javascript
1163 | function Jedi(options) {
1164 | options || (options = {});
1165 | var lightsaber = options.lightsaber || 'blue';
1166 | this.set('lightsaber', lightsaber);
1167 | }
1168 |
1169 | Jedi.prototype.set = function(key, val) {
1170 | this[key] = val;
1171 | };
1172 |
1173 | Jedi.prototype.get = function(key) {
1174 | return this[key];
1175 | };
1176 | ```
1177 |
1178 | **[⬆ back to top](#table-of-contents)**
1179 |
1180 |
1181 | ## Constructors
1182 |
1183 | - 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!
1184 |
1185 | ```javascript
1186 | function Jedi() {
1187 | console.log('new jedi');
1188 | }
1189 |
1190 | // bad
1191 | Jedi.prototype = {
1192 | fight: function fight() {
1193 | console.log('fighting');
1194 | },
1195 |
1196 | block: function block() {
1197 | console.log('blocking');
1198 | }
1199 | };
1200 |
1201 | // good
1202 | Jedi.prototype.fight = function fight() {
1203 | console.log('fighting');
1204 | };
1205 |
1206 | Jedi.prototype.block = function block() {
1207 | console.log('blocking');
1208 | };
1209 | ```
1210 |
1211 | - Methods can return `this` to help with method chaining.
1212 |
1213 | ```javascript
1214 | // bad
1215 | Jedi.prototype.jump = function() {
1216 | this.jumping = true;
1217 | return true;
1218 | };
1219 |
1220 | Jedi.prototype.setHeight = function(height) {
1221 | this.height = height;
1222 | };
1223 |
1224 | var luke = new Jedi();
1225 | luke.jump(); // => true
1226 | luke.setHeight(20) // => undefined
1227 |
1228 | // good
1229 | Jedi.prototype.jump = function() {
1230 | this.jumping = true;
1231 | return this;
1232 | };
1233 |
1234 | Jedi.prototype.setHeight = function(height) {
1235 | this.height = height;
1236 | return this;
1237 | };
1238 |
1239 | var luke = new Jedi();
1240 |
1241 | luke.jump()
1242 | .setHeight(20);
1243 | ```
1244 |
1245 |
1246 | - It's okay to write a custom toString() method, just make sure it works successfully and causes no side effects.
1247 |
1248 | ```javascript
1249 | function Jedi(options) {
1250 | options || (options = {});
1251 | this.name = options.name || 'no name';
1252 | }
1253 |
1254 | Jedi.prototype.getName = function getName() {
1255 | return this.name;
1256 | };
1257 |
1258 | Jedi.prototype.toString = function toString() {
1259 | return 'Jedi - ' + this.getName();
1260 | };
1261 | ```
1262 |
1263 | **[⬆ back to top](#table-of-contents)**
1264 |
1265 |
1266 | ## Events
1267 |
1268 | - When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass a hash instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event. For example, instead of:
1269 |
1270 | ```js
1271 | // bad
1272 | $(this).trigger('listingUpdated', listing.id);
1273 |
1274 | ...
1275 |
1276 | $(this).on('listingUpdated', function(e, listingId) {
1277 | // do something with listingId
1278 | });
1279 | ```
1280 |
1281 | prefer:
1282 |
1283 | ```js
1284 | // good
1285 | $(this).trigger('listingUpdated', { listingId : listing.id });
1286 |
1287 | ...
1288 |
1289 | $(this).on('listingUpdated', function(e, data) {
1290 | // do something with data.listingId
1291 | });
1292 | ```
1293 |
1294 | **[⬆ back to top](#table-of-contents)**
1295 |
1296 |
1297 | ## Modules
1298 |
1299 | - The module should start with a `!`. This ensures that if a malformed module forgets to include a final semicolon there aren't errors in production when the scripts get concatenated. [Explanation](https://github.com/airbnb/javascript/issues/44#issuecomment-13063933)
1300 | - The file should be named with camelCase, live in a folder with the same name, and match the name of the single export.
1301 | - Add a method called `noConflict()` that sets the exported module to the previous version and returns this one.
1302 | - Always declare `'use strict';` at the top of the module.
1303 |
1304 | ```javascript
1305 | // fancyInput/fancyInput.js
1306 |
1307 | !function(global) {
1308 | 'use strict';
1309 |
1310 | var previousFancyInput = global.FancyInput;
1311 |
1312 | function FancyInput(options) {
1313 | this.options = options || {};
1314 | }
1315 |
1316 | FancyInput.noConflict = function noConflict() {
1317 | global.FancyInput = previousFancyInput;
1318 | return FancyInput;
1319 | };
1320 |
1321 | global.FancyInput = FancyInput;
1322 | }(this);
1323 | ```
1324 |
1325 | **[⬆ back to top](#table-of-contents)**
1326 |
1327 |
1328 | ## jQuery
1329 |
1330 | - Prefix jQuery object variables with a `$`.
1331 |
1332 | ```javascript
1333 | // bad
1334 | var sidebar = $('.sidebar');
1335 |
1336 | // good
1337 | var $sidebar = $('.sidebar');
1338 | ```
1339 |
1340 | - Cache jQuery lookups.
1341 |
1342 | ```javascript
1343 | // bad
1344 | function setSidebar() {
1345 | $('.sidebar').hide();
1346 |
1347 | // ...stuff...
1348 |
1349 | $('.sidebar').css({
1350 | 'background-color': 'pink'
1351 | });
1352 | }
1353 |
1354 | // good
1355 | function setSidebar() {
1356 | var $sidebar = $('.sidebar');
1357 | $sidebar.hide();
1358 |
1359 | // ...stuff...
1360 |
1361 | $sidebar.css({
1362 | 'background-color': 'pink'
1363 | });
1364 | }
1365 | ```
1366 |
1367 | - For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
1368 | - Use `find` with scoped jQuery object queries.
1369 |
1370 | ```javascript
1371 | // bad
1372 | $('ul', '.sidebar').hide();
1373 |
1374 | // bad
1375 | $('.sidebar').find('ul').hide();
1376 |
1377 | // good
1378 | $('.sidebar ul').hide();
1379 |
1380 | // good
1381 | $('.sidebar > ul').hide();
1382 |
1383 | // good
1384 | $sidebar.find('ul').hide();
1385 | ```
1386 |
1387 | **[⬆ back to top](#table-of-contents)**
1388 |
1389 |
1390 | ## ECMAScript 5 Compatibility
1391 |
1392 | - Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](http://kangax.github.com/es5-compat-table/)
1393 |
1394 | **[⬆ back to top](#table-of-contents)**
1395 |
1396 |
1397 | ## Testing
1398 |
1399 | - **Yup.**
1400 |
1401 | ```javascript
1402 | function() {
1403 | return true;
1404 | }
1405 | ```
1406 |
1407 | **[⬆ back to top](#table-of-contents)**
1408 |
1409 |
1410 | ## Performance
1411 |
1412 | - [On Layout & Web Performance](http://kellegous.com/j/2013/01/26/layout-performance/)
1413 | - [String vs Array Concat](http://jsperf.com/string-vs-array-concat/2)
1414 | - [Try/Catch Cost In a Loop](http://jsperf.com/try-catch-in-loop-cost)
1415 | - [Bang Function](http://jsperf.com/bang-function)
1416 | - [jQuery Find vs Context, Selector](http://jsperf.com/jquery-find-vs-context-sel/13)
1417 | - [innerHTML vs textContent for script text](http://jsperf.com/innerhtml-vs-textcontent-for-script-text)
1418 | - [Long String Concatenation](http://jsperf.com/ya-string-concat)
1419 | - Loading...
1420 |
1421 | **[⬆ back to top](#table-of-contents)**
1422 |
1423 |
1424 | ## Resources
1425 |
1426 |
1427 | **Read This**
1428 |
1429 | - [Annotated ECMAScript 5.1](http://es5.github.com/)
1430 |
1431 | **Other Styleguides**
1432 |
1433 | - [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml)
1434 | - [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
1435 | - [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwldrn/idiomatic.js/)
1436 |
1437 | **Other Styles**
1438 |
1439 | - [Naming this in nested functions](https://gist.github.com/4135065) - Christian Johansen
1440 | - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52)
1441 | - [Popular JavaScript Coding Conventions on Github](http://sideeffect.kr/popularconvention/#javascript)
1442 |
1443 | **Further Reading**
1444 |
1445 | - [Understanding JavaScript Closures](http://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
1446 | - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
1447 | - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
1448 | - [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
1449 |
1450 | **Books**
1451 |
1452 | - [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
1453 | - [JavaScript Patterns](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
1454 | - [Pro JavaScript Design Patterns](http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
1455 | - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
1456 | - [Maintainable JavaScript](http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
1457 | - [JavaScript Web Applications](http://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
1458 | - [Pro JavaScript Techniques](http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
1459 | - [Smashing Node.js: JavaScript Everywhere](http://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
1460 | - [Secrets of the JavaScript Ninja](http://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
1461 | - [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
1462 | - [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
1463 | - [JSBooks](http://jsbooks.revolunet.com/)
1464 | - [Third Party JavaScript](http://manning.com/vinegar/) - Ben Vinegar and Anton Kovalyov
1465 |
1466 | **Blogs**
1467 |
1468 | - [DailyJS](http://dailyjs.com/)
1469 | - [JavaScript Weekly](http://javascriptweekly.com/)
1470 | - [JavaScript, JavaScript...](http://javascriptweblog.wordpress.com/)
1471 | - [Bocoup Weblog](http://weblog.bocoup.com/)
1472 | - [Adequately Good](http://www.adequatelygood.com/)
1473 | - [NCZOnline](http://www.nczonline.net/)
1474 | - [Perfection Kills](http://perfectionkills.com/)
1475 | - [Ben Alman](http://benalman.com/)
1476 | - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
1477 | - [Dustin Diaz](http://dustindiaz.com/)
1478 | - [nettuts](http://net.tutsplus.com/?s=javascript)
1479 |
1480 | **[⬆ back to top](#table-of-contents)**
1481 |
1482 | ## In the Wild
1483 |
1484 | 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.
1485 |
1486 | - **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript)
1487 | - **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript)
1488 | - **American Insitutes for Research**: [AIRAST/javascript](https://github.com/AIRAST/javascript)
1489 | - **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide)
1490 | - **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript)
1491 | - **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript)
1492 | - **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript)
1493 | - **Gawker Media**: [gawkermedia/javascript](https://github.com/gawkermedia/javascript)
1494 | - **GeneralElectric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript)
1495 | - **GoodData**: [gooddata/gdc-js-style](https://github.com/gooddata/gdc-js-style)
1496 | - **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript)
1497 | - **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript)
1498 | - **Intent Media**: [intentmedia/javascript](https://github.com/intentmedia/javascript)
1499 | - **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript)
1500 | - **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript)
1501 | - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript)
1502 | - **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript)
1503 | - **Muber**: [muber/javascript](https://github.com/muber/javascript)
1504 | - **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript)
1505 | - **National Park Service**: [nationalparkservice/javascript](https://github.com/nationalparkservice/javascript)
1506 | - **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript)
1507 | - **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript)
1508 | - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide)
1509 | - **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript)
1510 | - **REI**: [reidev/js-style-guide](https://github.com/reidev/js-style-guide)
1511 | - **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide)
1512 | - **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
1513 | - **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
1514 | - **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
1515 | - **Userify**: [userify/javascript](https://github.com/userify/javascript)
1516 | - **Zillow**: [zillow/javascript](https://github.com/zillow/javascript)
1517 | - **ZocDoc**: [ZocDoc/javascript](https://github.com/ZocDoc/javascript)
1518 |
1519 | ## Translation
1520 |
1521 | This style guide is also available in other languages:
1522 |
1523 | - :de: **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
1524 | - :jp: **Japanese**: [mitsuruog/javacript-style-guide](https://github.com/mitsuruog/javacript-style-guide)
1525 | - :br: **Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide)
1526 | - :cn: **Chinese**: [adamlu/javascript-style-guide](https://github.com/adamlu/javascript-style-guide)
1527 | - :es: **Spanish**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide)
1528 | - :kr: **Korean**: [tipjs/javascript-style-guide](https://github.com/tipjs/javascript-style-guide)
1529 | - :fr: **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
1530 | - :ru: **Russian**: [uprock/javascript](https://github.com/uprock/javascript)
1531 | - :bg: **Bulgarian**: [borislavvv/javascript](https://github.com/borislavvv/javascript)
1532 |
1533 | ## The JavaScript Style Guide Guide
1534 |
1535 | - [Reference](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide)
1536 |
1537 | ## Contributors
1538 |
1539 | - [View Contributors](https://github.com/airbnb/javascript/graphs/contributors)
1540 |
1541 |
1542 | ## License
1543 |
1544 | (The MIT License)
1545 |
1546 | Copyright (c) 2014 Airbnb
1547 |
1548 | Permission is hereby granted, free of charge, to any person obtaining
1549 | a copy of this software and associated documentation files (the
1550 | 'Software'), to deal in the Software without restriction, including
1551 | without limitation the rights to use, copy, modify, merge, publish,
1552 | distribute, sublicense, and/or sell copies of the Software, and to
1553 | permit persons to whom the Software is furnished to do so, subject to
1554 | the following conditions:
1555 |
1556 | The above copyright notice and this permission notice shall be
1557 | included in all copies or substantial portions of the Software.
1558 |
1559 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
1560 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1561 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1562 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1563 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1564 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1565 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1566 |
1567 | **[⬆ back to top](#table-of-contents)**
1568 |
1569 | # };
1570 |
--------------------------------------------------------------------------------
/linters/SublimeLinter/SublimeLinter.sublime-settings:
--------------------------------------------------------------------------------
1 | /**
2 | * Airbnb JSHint settings for use with SublimeLinter and Sublime Text 2.
3 | *
4 | * 1. Install SublimeLinter at https://github.com/SublimeLinter/SublimeLinter
5 | * 2. Open user preferences for the SublimeLinter package in Sublime Text 2
6 | * * For Mac OS X go to _Sublime Text 2_ > _Preferences_ > _Package Settings_ > _SublimeLinter_ > _Settings - User_
7 | * 3. Paste the contents of this file into your settings file
8 | * 4. Save the settings file
9 | *
10 | * @version 0.3.0
11 | * @see https://github.com/SublimeLinter/SublimeLinter
12 | * @see http://www.jshint.com/docs/
13 | */
14 | {
15 | "jshint_options":
16 | {
17 | /*
18 | * ENVIRONMENTS
19 | * =================
20 | */
21 |
22 | // Define globals exposed by modern browsers.
23 | "browser": true,
24 |
25 | // Define globals exposed by jQuery.
26 | "jquery": true,
27 |
28 | // Define globals exposed by Node.js.
29 | "node": true,
30 |
31 | /*
32 | * ENFORCING OPTIONS
33 | * =================
34 | */
35 |
36 | // Force all variable names to use either camelCase style or UPPER_CASE
37 | // with underscores.
38 | "camelcase": true,
39 |
40 | // Prohibit use of == and != in favor of === and !==.
41 | "eqeqeq": true,
42 |
43 | // Suppress warnings about == null comparisons.
44 | "eqnull": true,
45 |
46 | // Enforce tab width of 2 spaces.
47 | "indent": 2,
48 |
49 | // Prohibit use of a variable before it is defined.
50 | "latedef": true,
51 |
52 | // Require capitalized names for constructor functions.
53 | "newcap": true,
54 |
55 | // Enforce use of single quotation marks for strings.
56 | "quotmark": "single",
57 |
58 | // Prohibit trailing whitespace.
59 | "trailing": true,
60 |
61 | // Prohibit use of explicitly undeclared variables.
62 | "undef": true,
63 |
64 | // Warn when variables are defined but never used.
65 | "unused": true,
66 |
67 | // Enforce line length to 80 characters
68 | "maxlen": 80,
69 |
70 | // Enforce placing 'use strict' at the top function scope
71 | "strict": true
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/linters/jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | /*
3 | * ENVIRONMENTS
4 | * =================
5 | */
6 |
7 | // Define globals exposed by modern browsers.
8 | "browser": true,
9 |
10 | // Define globals exposed by jQuery.
11 | "jquery": true,
12 |
13 | // Define globals exposed by Node.js.
14 | "node": true,
15 |
16 | /*
17 | * ENFORCING OPTIONS
18 | * =================
19 | */
20 |
21 | // Force all variable names to use either camelCase style or UPPER_CASE
22 | // with underscores.
23 | "camelcase": true,
24 |
25 | // Prohibit use of == and != in favor of === and !==.
26 | "eqeqeq": true,
27 |
28 | // Enforce tab width of 2 spaces.
29 | "indent": 2,
30 |
31 | // Prohibit use of a variable before it is defined.
32 | "latedef": true,
33 |
34 | // Enforce line length to 80 characters
35 | "maxlen": 80,
36 |
37 | // Require capitalized names for constructor functions.
38 | "newcap": true,
39 |
40 | // Enforce use of single quotation marks for strings.
41 | "quotmark": "single",
42 |
43 | // Enforce placing 'use strict' at the top function scope
44 | "strict": true,
45 |
46 | // Prohibit use of explicitly undeclared variables.
47 | "undef": true,
48 |
49 | // Warn when variables are defined but never used.
50 | "unused": true,
51 |
52 | /*
53 | * RELAXING OPTIONS
54 | * =================
55 | */
56 |
57 | // Suppress warnings about == null comparisons.
58 | "eqnull": true
59 | }
60 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "airbnb-style",
3 | "version": "1.0.0",
4 | "description": "A mostly reasonable approach to JavaScript.",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/airbnb/javascript.git"
11 | },
12 | "keywords": [
13 | "style guide",
14 | "lint",
15 | "airbnb"
16 | ],
17 | "author": "Harrison Shoff (https://twitter.com/hshoff)",
18 | "license": "MIT",
19 | "bugs": {
20 | "url": "https://github.com/airbnb/javascript/issues"
21 | },
22 | "homepage": "https://github.com/airbnb/javascript"
23 | }
24 |
--------------------------------------------------------------------------------