├── README.md
├── linters
├── SublimeLinter
│ └── SublimeLinter.sublime-settings
└── jshintrc
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 | # Dobre Praktyki JavaScriptu by Airbnb() {
2 |
3 | *Najbardziej sensowne podejście do programowania w JavaScripcie*
4 |
5 |
6 | ## Spis Treści
7 |
8 | 1. [Typy](#typy)
9 | 1. [Obiekty](#obiekty)
10 | 1. [Tablice](#tablice)
11 | 1. [Stringi](#stringi)
12 | 1. [Funkcje](#funkcje)
13 | 1. [Własności](#wlasnosci)
14 | 1. [Zmienne](#zmienne)
15 | 1. [Hoisting](#hoisting)
16 | 1. [Warunki i równości](#warunki-i-rownosci)
17 | 1. [Bloki kodu](#bloki-kodu)
18 | 1. [Komentarze](#komentarze)
19 | 1. [Białe znaki](#biale-znaki)
20 | 1. [Przecinki](#przecinki)
21 | 1. [Średniki](#sredniki)
22 | 1. [Rzutowania i korekcje typów](#rzutowania-i-korekcje-typow)
23 | 1. [Nazwy zmiennych i funkcji](#nazwy-zmiennych-i-funkcji)
24 | 1. [Gettery i settery](#gettery-i-settery)
25 | 1. [Konstruktory](#konstruktory)
26 | 1. [Eventy](#eventy)
27 | 1. [Moduły](#moduly)
28 | 1. [jQuery](#jquery)
29 | 1. [Standard ECMAScript 5](#standard-ecmascript-5)
30 | 1. [Testowanie](#testowanie)
31 | 1. [Wydajność](#wydajnosc)
32 | 1. [Więcej do czytania](#wiecej-do-czytania)
33 | 1. [Kto właściwie z tego korzysta w praktyce](#kto-wlasciwie-z-tego-korzysta-w-praktyce)
34 | 1. [Tłumaczenia](#tlumaczenia)
35 | 1. [Poradnik do poradnika tego poradnika](#poradnik-do-poradnika-tego-poradnika)
36 | 1. [Pogadaj z nami o JavaScripcie](#pogadaj-z-nami-o-javascriptcie)
37 | 1. [Współtwórcy](#wspoltworcy)
38 | 1. [Licencja](#licencja)
39 |
40 | ## Typy
41 |
42 | - **Typy proste**: Operując na typach prostych, działasz bezpośrednio na ich wartościach. Typy proste to:
43 |
44 | + `string`
45 | + `number`
46 | + `boolean`
47 | + `null`
48 | + `undefined`
49 |
50 | ```javascript
51 | var foo = 1,
52 | bar = foo;
53 |
54 | bar = 9;
55 |
56 | console.log(foo, bar); // => 1, 9
57 | ```
58 | - **Typy złożone**: Pracując ze zmienną o złożonym typie, modyfikujesz wartość wskazywaną przez referencję/wskaźnik. Typy złożone to:
59 |
60 | + `object`
61 | + `array`
62 | + `function`
63 |
64 | ```javascript
65 | var foo = [1, 2],
66 | bar = foo; // referencja do 'foo' przypisana do 'bar'
67 |
68 | bar[0] = 9;
69 |
70 | console.log(foo[0], bar[0]); // => 9, 9
71 | ```
72 |
73 | **[⬆ do góry](#table-of-contents)**
74 |
75 | ## Obiekty
76 |
77 | - Zamiast konstruktorów i `new`, używaj klamerek do tworzenia nowych obiektów.
78 |
79 | ```javascript
80 | // źle
81 | var item = new Object();
82 |
83 | // dobrze
84 | var item = {};
85 | ```
86 |
87 | - Nie używaj [słów kluczowych JavaScriptu](http://es5.github.io/#x7.6.1) jako nazw pól w tablicach i obiektach. Nie będą działać pod IE8. [Więcej info](https://github.com/airbnb/javascript/issues/61).
88 |
89 | ```javascript
90 | // źle
91 | var superman = {
92 | default: { clark: 'kent' },
93 | private: true
94 | };
95 |
96 | // dobrze
97 | var superman = {
98 | defaults: { clark: 'kent' },
99 | hidden: true
100 | };
101 | ```
102 |
103 | - Zamiast słów kluczowych używaj sensownych synonimów.
104 |
105 | ```javascript
106 | // źle
107 | var superman = {
108 | class: 'alien'
109 | };
110 |
111 | // źle
112 | var superman = {
113 | klass: 'alien'
114 | };
115 |
116 | // dobrze
117 | var superman = {
118 | type: 'alien'
119 | };
120 | ```
121 |
122 | **[⬆ do góry](#table-of-contents)**
123 |
124 | ## Tablice
125 |
126 | - Używaj nawiasów kwadratowych do tworzenia tablic, zamiast konstruktorów.
127 |
128 | ```javascript
129 | // źle
130 | var items = new Array();
131 |
132 | // dobrze
133 | var items = [];
134 | ```
135 |
136 | - Jeżeli nie znasz długości tablicy, dodawaj do niej elementy przy pomocy metody Array#push.
137 |
138 | ```javascript
139 | var someStack = [];
140 |
141 |
142 | // źle
143 | someStack[someStack.length] = 'abracadabra';
144 |
145 | // dobrze
146 | someStack.push('abracadabra');
147 | ```
148 |
149 | - Do kopiowania tablic używaj metody Array#slice. [jsPerf](http://jsperf.com/converting-arguments-to-an-array/7)
150 |
151 | ```javascript
152 | var len = items.length,
153 | itemsCopy = [],
154 | i;
155 |
156 | // źle
157 | for (i = 0; i < len; i++) {
158 | itemsCopy[i] = items[i];
159 | }
160 |
161 | // dobrze
162 | itemsCopy = items.slice();
163 | ```
164 |
165 | - Aby zamienić tablico-podobny obiekt w tablicę, używaj metody Array#slice.
166 |
167 | ```javascript
168 | function trigger() {
169 | var args = Array.prototype.slice.call(arguments);
170 | ...
171 | }
172 | ```
173 |
174 | **[⬆ do góry](#table-of-contents)**
175 |
176 |
177 | ## Stringi
178 |
179 | - Używaj pojedynczego cudzysłowu podczas zapisywania Stringów.
180 |
181 | ```javascript
182 | // źle
183 | var name = "Bob Parr";
184 |
185 | // dobrze
186 | var name = 'Bob Parr';
187 |
188 | // źle
189 | var fullName = "Bob " + this.lastName;
190 |
191 | // dobrze
192 | var fullName = 'Bob ' + this.lastName;
193 | ```
194 |
195 | - Tekst dłuższy niż 80 znaków powinieneś zapisywać dzieląc go na kilka osobnych linii.
196 | - Jedna uwaga: Przy nadmiernym stosowaniu powyższej zasady, łączone Stringi mogą wpływać negatywnie na działanie aplikacji. [jsPerf](http://jsperf.com/ya-string-concat) & [Dyskusja na GitHub](https://github.com/airbnb/javascript/issues/40)
197 |
198 | ```javascript
199 | // źle
200 | 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.';
201 |
202 | // źle
203 | var errorMessage = 'This is a super long error that was thrown because \
204 | of Batman. When you stop to think about how Batman had anything to do \
205 | with this, you would get nowhere \
206 | fast.';
207 |
208 | // dobrze
209 | var errorMessage = 'This is a super long error that was thrown because ' +
210 | 'of Batman. When you stop to think about how Batman had anything to do ' +
211 | 'with this, you would get nowhere fast.';
212 | ```
213 |
214 | - Kiedy tworzysz w kodzie długi tekst z kilku mniejszych, używaj metody Array#join zamiast dodawać Stringi przy pomocy operatora. Głównie ze względu na działanie pod IE: [jsPerf](http://jsperf.com/string-vs-array-concat/2).
215 |
216 | ```javascript
217 | var items,
218 | messages,
219 | length,
220 | i;
221 |
222 | messages = [{
223 | state: 'success',
224 | message: 'This one worked.'
225 | }, {
226 | state: 'success',
227 | message: 'This one worked as well.'
228 | }, {
229 | state: 'error',
230 | message: 'This one did not work.'
231 | }];
232 |
233 | length = messages.length;
234 |
235 | // źle
236 | function inbox(messages) {
237 | items = '
';
238 |
239 | for (i = 0; i < length; i++) {
240 | items += '- ' + messages[i].message + '
';
241 | }
242 |
243 | return items + '
';
244 | }
245 |
246 | // dobrze
247 | function inbox(messages) {
248 | items = [];
249 |
250 | for (i = 0; i < length; i++) {
251 | items[i] = messages[i].message;
252 | }
253 |
254 | return '';
255 | }
256 | ```
257 |
258 | **[⬆ na góre](#table-of-contents)**
259 |
260 |
261 | ## Funkcje
262 |
263 | - Sposoby zapisu funkcji w JavaScripcie:
264 |
265 | ```javascript
266 | // funkcja anonimowa
267 | var anonymous = function() {
268 | return true;
269 | };
270 |
271 | // wyrażenie funkcji przy pomocy zmiennej
272 | var named = function named() {
273 | return true;
274 | };
275 |
276 | // funkcja wywołana natychmiast po utworzeniu (IIFE)
277 | (function() {
278 | console.log('Welcome to the Internet. Please follow me.');
279 | })();
280 | ```
281 |
282 | - Nigdy nie deklaruj nowej funkcji w bloku warunkowym ani iteracyjnym (if, while itp). Przeglądarki pozwolą Ci na takie deklarowanie, ale każda będzie interpretowała to na swój sposób. Zamiast tego zapisuj funkcje przy pomocy zmiennej.
283 | - **Note:** ECMA-262 definiuje blok jako listę komend. Deklaracja funkcji to nie komenda. [Więcej o ECMA-262 i tym problemie](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf#page=97).
284 |
285 | ```javascript
286 | // źle
287 | if (currentUser) {
288 | function test() {
289 | console.log('Nope.');
290 | }
291 | }
292 |
293 | // dobrze
294 | var test;
295 | if (currentUser) {
296 | test = function test() {
297 | console.log('Yup.');
298 | };
299 | }
300 | ```
301 |
302 | - Nie nadawaj żadnej funkcji argumentu o nazwie 'arguments'. Jest to jeden z domyślnie tworzonych parametrów dla każdej nowej funkcji i nie powinieneś go nadpisywać, zmieniać jego zachowania ani wartości.
303 |
304 | ```javascript
305 | // źle
306 | function nope(name, options, arguments) {
307 | // ...kod...
308 | }
309 |
310 | // dobrze
311 | function yup(name, options, args) {
312 | // ...kod...
313 | }
314 | ```
315 |
316 | **[⬆ do góry](#table-of-contents)**
317 |
318 |
319 |
320 | ## Własności
321 |
322 | - Jeżeli nazwa parametru obiektu jest statyczna i znasz ją, używaj kropki, aby odczytać wartość tego parametru.
323 |
324 | ```javascript
325 | var luke = {
326 | jedi: true,
327 | age: 28
328 | };
329 |
330 | // źle
331 | var isJedi = luke['jedi'];
332 |
333 | // dobrze
334 | var isJedi = luke.jedi;
335 | ```
336 |
337 | - Jeżeli natomiast nazwa jest dynamiczna, używaj nawiasów kwadratowych.
338 |
339 | ```javascript
340 | var luke = {
341 | jedi: true,
342 | age: 28
343 | };
344 |
345 | function getProp(prop) {
346 | return luke[prop];
347 | }
348 |
349 | var isJedi = getProp('jedi');
350 | ```
351 |
352 | **[⬆ do góry](#table-of-contents)**
353 |
354 |
355 | ## Zmienne
356 |
357 | - Zawsze używaj słowa kluczowego 'var', aby tworzyć nowe zmienne. W przeciwnym wypadku będą one automatycznie przypisywane do bloku globalnego i mogą namieszać w aplikacji. Unikaj zmiennych globalnych zawsze, gdy jest to możliwe.
358 |
359 | ```javascript
360 | // źle
361 | superPower = new SuperPower();
362 |
363 | // dobrze
364 | var superPower = new SuperPower();
365 | ```
366 |
367 | - Jeżeli tworzysz kilka zmiennych, używaj do tego pojedynczego słówka 'var', a kolejne zmienne dodawaj w nowych linijkach, oddzielając je przecinkami.
368 |
369 | ```javascript
370 | // źle
371 | var items = getItems();
372 | var goSportsTeam = true;
373 | var dragonball = 'z';
374 |
375 | // dobrze
376 | var items = getItems(),
377 | goSportsTeam = true,
378 | dragonball = 'z';
379 | ```
380 |
381 | - Niezdefiniowane zmienne deklaruj na końcu. Dzięki temu będziesz miał zawsze możliwość nadania im wartości na bazie wcześniej utworzonych zmiennych.
382 |
383 | ```javascript
384 | // źle
385 | var i, len, dragonball,
386 | items = getItems(),
387 | goSportsTeam = true;
388 |
389 | // źle
390 | var i, items = getItems(),
391 | dragonball,
392 | goSportsTeam = true,
393 | len;
394 |
395 | // dobrze
396 | var items = getItems(),
397 | goSportsTeam = true,
398 | dragonball,
399 | length,
400 | i;
401 | ```
402 |
403 | - Nowe zmienne deklaruj zawsze na początku bloku w którym je tworzysz ( na początku scope'u ). JavaScript w przeciwnym razie przeniesie je tam za Ciebie 'w tle', a to może doprowadzić do niespodziewanych błędów ( Więcej w części - Hoisting ).
404 |
405 | ```javascript
406 | // źle
407 | function() {
408 | test();
409 | console.log('doing stuff..');
410 |
411 | //..kod..
412 |
413 | var name = getName();
414 |
415 | if (name === 'test') {
416 | return false;
417 | }
418 |
419 | return name;
420 | }
421 |
422 | // dobrze
423 | function() {
424 | var name = getName();
425 |
426 | test();
427 | console.log('doing stuff..');
428 |
429 | //..kod..
430 |
431 | if (name === 'test') {
432 | return false;
433 | }
434 |
435 | return name;
436 | }
437 |
438 | // źle
439 | function() {
440 | var name = getName();
441 |
442 | if (!arguments.length) {
443 | return false;
444 | }
445 |
446 | return true;
447 | }
448 |
449 | // dobrze
450 | function() {
451 | if (!arguments.length) {
452 | return false;
453 | }
454 |
455 | var name = getName();
456 |
457 | return true;
458 | }
459 | ```
460 |
461 | **[⬆ do góry](#table-of-contents)**
462 |
463 |
464 | ## Hoisting
465 |
466 | - Deklaracje zmiennych są automatycznie przenoszone przez JavaScript na początek bloku w którym zostały utworzone i w którym działają - w obrębie tzw. scope'u. Przypisywane wartości nie są przenoszone. Dla osób, które zwykle używały języków C++/Java może się to wydać z początku lekko nielogiczne, ponieważ JavaScript pozwala na użycie zmiennej, która w danym miejscu w kodzie jeszcze nie istnieje.
467 |
468 | ```javascript
469 | // to nie powinno zadziałać (o ile tylko
470 | // nie ma zmiennej globalnej notDefined)
471 | function example() {
472 | console.log(notDefined); // => wyrzuca błąd ReferenceError
473 | }
474 |
475 | // deklaracja zmiennej, nawet po jej wykorzystaniu
476 | // w kodzie, pozbywa się błędu. Dzięki hoistingowi
477 | // deklaracja jest automatycznie przenoszona na
478 | // początek funkcji.
479 | // Wartość 'true' nie zostaje przeniesiona.
480 | function example() {
481 | console.log(declaredButNotAssigned); // => undefined
482 | var declaredButNotAssigned = true;
483 | }
484 |
485 | // poprzedni przykład, w rozumieniu interpretera
486 | // JavaScriptu, wygląda tak:
487 | function example() {
488 | var declaredButNotAssigned;
489 | console.log(declaredButNotAssigned); // => undefined
490 | declaredButNotAssigned = true;
491 | }
492 | ```
493 |
494 | - Anonimowe funkcje zapisane w zmiennych działają na podobnej zasadzie. Ich nazwa zostaje
495 | przeniesiona na początek scope'u, a sama wartość, tj. wnętrze funkcji, pozostaje na swoim
496 | miejscu.
497 |
498 | ```javascript
499 | function example() {
500 | console.log(anonymous); // => undefined
501 |
502 | anonymous(); // => TypeError anonymous is not a function
503 |
504 | var anonymous = function() {
505 | console.log('anonymous function expression');
506 | };
507 | }
508 | ```
509 |
510 | - Funkcje zapisane w zmiennych, posiadające swoją własną nazwę, tracą ją. Na początek scope'u
511 | wyniesiona zostaje nazwa zmiennej do której funkcja została przypisana.
512 |
513 | ```javascript
514 | function example() {
515 | console.log(named); // => undefined
516 |
517 | named(); // => TypeError named is not a function
518 |
519 | superPower(); // => ReferenceError superPower is not defined
520 |
521 | var named = function superPower() {
522 | console.log('Flying');
523 | };
524 | }
525 |
526 | // to samo dotyczy funkcji, których
527 | // nazwa jest taka sama jak nazwa
528 | // okupowanej zmiennej - ale to
529 | // w miarę logiczne
530 | function example() {
531 | console.log(named); // => undefined
532 |
533 | named(); // => TypeError named is not a function
534 |
535 | var named = function named() {
536 | console.log('named');
537 | }
538 | }
539 | ```
540 |
541 | - Funkcje nieprzypisane do zmiennych zostają automatycznie wyniesione na początek scope'a.
542 |
543 | ```javascript
544 | function example() {
545 | superPower(); // => Flying
546 |
547 | function superPower() {
548 | console.log('Flying');
549 | }
550 | }
551 | ```
552 |
553 | - Więcej informacji na temat działania JavaScriptu, scope'ów i hoistingu: [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) by [Ben Cherry](http://www.adequatelygood.com/)
554 |
555 | **[⬆ na górę](#table-of-contents)**
556 |
557 |
558 |
559 | ## Warunki i równości
560 |
561 | - Używaj `===` i `!==` zamiast `==` i `!=`.
562 | - Wyrażenia warunkowe zawsze rzutowane są przy pomocy metody toBoolean(), której zasada działania wyglądaja następująco:
563 |
564 | + **Jakikolwiek Obiekt** równy jest **true**
565 | + **Undefined** równe jest **false**
566 | + **Null** równe jest **false**
567 | + **Boolean** równy jest **swojej wartości**
568 | + **Liczby** - **false** jeżeli **+0, -0, lub NaN**, w przeciwnym razie **true**
569 | + **Stringi** równe są **false** jeżeli są puste `''`, w przeciwnym razie **true**
570 |
571 | ```javascript
572 | if ([0]) {
573 | // true
574 | // Tablica to obiekt, obiekty są zawsze równe true
575 | }
576 | ```
577 |
578 | - Staraj się zapisywać warunki w jak najkrótszej formie, jeżeli jest to możliwe.
579 |
580 | ```javascript
581 | // źle
582 | if (name !== '') {
583 | // ...kod...
584 | }
585 |
586 | // dobrze
587 | if (name) {
588 | // ...kod...
589 | }
590 |
591 | // źle
592 | if (collection.length > 0) {
593 | // ...kod...
594 | }
595 |
596 | // dobrze
597 | if (collection.length) {
598 | // ...kod...
599 | }
600 | ```
601 |
602 | - Więcej informacji: [Truth Equality and JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll
603 |
604 | **[⬆ na górę](#table-of-contents)**
605 |
606 |
607 | ## Bloki kodu
608 |
609 | - Jeżeli twój kod ma więcej niż jedną linijkę, obejmij go klamerkami.
610 |
611 | ```javascript
612 | // źle
613 | if (test)
614 | return false;
615 |
616 | // dobrze
617 | if (test) return false;
618 |
619 | // źle
620 | if (test) {
621 | return false;
622 | }
623 |
624 | // źle
625 | function() { return false; }
626 |
627 | // dobrze
628 | function() {
629 | return false;
630 | }
631 | ```
632 |
633 | **[⬆ do góry](#table-of-contents)**
634 |
635 |
636 | ## Komentarze
637 |
638 | - Do długich, kilkuwierszowych komentarzy używaj zapisu `/** ... */`. W komentarzach zawieraj takie informacje jak: krótki opis, listę użytych typów zmiennych, argumenty funkcji i zwracane wartości.
639 | kod
640 | ```javascript
641 | // źle
642 | // make() zwraca nowy element
643 | // na podstawie podanego argumentu
644 | //
645 | // @param tag
646 | // @return element
647 | function make(tag) {
648 |
649 | // ...kod...
650 |
651 | return element;
652 | }
653 |
654 | // dobrze
655 | /**
656 | * make() zwraca nowy element
657 | * na podstawie podanego argumentu
658 | *
659 | * @param tag
660 | * @return element
661 | */
662 | function make(tag) {
663 |
664 | // ...kod...
665 |
666 | return element;
667 | }
668 | ```
669 |
670 | - Zapisu `//` używaj do krótkich, mieszących się w jednej linii komentarzy. Komentarze umieszczaj linijkę ponad opisywanymi elementami. Nad komentarzami dodawaj też jedną pustą linijkę, dla czytelności.
671 |
672 | ```javascript
673 | // źle
674 | var active = true; // jest aktywny
675 |
676 | // dobrze
677 | // jest aktywny
678 | var active = true;
679 |
680 | // źle
681 | function getType() {
682 | console.log('fetching type...');
683 | // ustaw domyślny typ na 'brak typu'
684 | var type = this._type || 'brak typu';
685 |
686 | return type;
687 | }
688 |
689 | // dobrze
690 | function getType() {
691 | console.log('fetching type...');
692 |
693 | // ustaw domyslny typ na 'brak typu'
694 | var type = this._type || 'brak typu';
695 |
696 | return type;
697 | }
698 | ```
699 | - Aby oznaczyć błędy, które trzeba będzie w przyszłości poprawić, używaj prefiksu 'FIXME'. Do oznaczania pomysłów, które mogą poczekać na swoją kolej, używaj 'TODO'. Pomoże to innym programistom w odszukaniu i zrozumieniu Twoich komentarzy. Takie specjalne znaczniki działają inaczej niż zwykłe komentarze. Nie niosą ze sobą konkretnych informacji, a raczej stanowią ogłoszenia dla innych programistów pracujących nad projektem. Przykładowo 'FIXME -- trzeba to później rozkminić' lub 'TODO -- trzeba by tutaj to dodać'.
700 |
701 | - Używaj `// FIXME:`, aby oznaczyć problemy w kodzie
702 |
703 | ```javascript
704 | function Calculator() {
705 |
706 | // FIXME: zmienna 'total' jest globalna
707 | total = 0;
708 |
709 | return this;
710 | }
711 | ```
712 |
713 | - Używaj `// TODO:`, aby oznaczyć pomysły
714 |
715 | ```javascript
716 | function Calculator() {
717 |
718 | // TODO: zmienna 'total' musi być konfigurowalna przez jakiś zewn. parametr
719 | this.total = 0;
720 |
721 | return this;
722 | }
723 | ```
724 |
725 | **[⬆ do góry](#table-of-contents)**
726 |
727 |
728 | ## Białe znaki
729 |
730 | - Używaj tabulatorów o szerokości 2 spacji.
731 |
732 | ```javascript
733 | // źle
734 | function() {
735 | ∙∙∙∙var name;
736 | }
737 |
738 | // źle
739 | function() {
740 | ∙var name;
741 | }
742 | kod
743 | // dobrze
744 | function() {
745 | ∙∙var name;
746 | }
747 | ```
748 |
749 | - Dodawaj pojedynczą spację przed rozpoczynającymi blok klamrami.
750 |
751 | ```javascript
752 | // źle
753 | function test(){
754 | console.log('test');
755 | }
756 |
757 | // dobrze
758 | function test() {
759 | console.log('test');
760 | }
761 |
762 | // źle
763 | dog.set('attr',{
764 | age: '1 year',
765 | breed: 'Bernese Mountain Dog'
766 | });
767 |
768 | // dobrze
769 | dog.set('attr', {
770 | age: '1 year',
771 | breed: 'Bernese Mountain Dog'
772 | });
773 | ```
774 |
775 | - Rozdzielaj równania spacjami tak, aby były czytelne.
776 |
777 | ```javascript
778 | // źle
779 | var x=y+5;
780 |
781 | // dobrze
782 | var x = y + 5;
783 | ```
784 |
785 | - Na końcu plików dodawaj pojedynczy enter.
786 |
787 | ```javascript
788 | // źle
789 | (function(global) {
790 | // ...kod...
791 | })(this);
792 | ```
793 |
794 | ```javascript
795 | // źle
796 | (function(global) {
797 | // ...kod...
798 | })(this);↵
799 | ↵
800 | ```
801 |
802 | ```javascript
803 | // dobrze
804 | (function(global) {
805 | // ...kod...
806 | })(this);↵
807 | ```
808 |
809 | - Łącząc metody wywołane na jednym elemencie w łańcuch, rozdzielaj je przy pomocy nowych linii i spacji.
810 |
811 | ```javascript
812 | // źle
813 | $('#items').find('.selected').highlight().end().find('.open').updateCount();
814 |
815 | // dobrze
816 | $('#items')
817 | .find('.selected')
818 | .highlight()
819 | .end()
820 | .find('.open')
821 | .updateCount();
822 |
823 | // źle
824 | var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true)
825 | .attr('width', (radius + margin) * 2).append('svg:g')
826 | .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
827 | .call(tron.led);
828 |
829 | // dobrze
830 | var leds = stage.selectAll('.led')
831 | .data(data)
832 | .enter().append('svg:svg')
833 | .class('led', true)
834 | .attr('width', (radius + margin) * 2)
835 | .append('svg:g')
836 | .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
837 | .call(tron.led);
838 | ```
839 |
840 | **[⬆ do góry](#table-of-contents)**
841 |
842 | ## Przecinki
843 |
844 | - **Nie** dodawaj przecinków przed zmiennymi w tablicach, obiektach i grupach.
845 |
846 | ```javascript
847 | // źle
848 | var once
849 | , upon
850 | , aTime;
851 |
852 | // dobrze
853 | var once,
854 | upon,
855 | aTime;
856 |
857 | // źle
858 | var hero = {
859 | firstName: 'Bob'
860 | , lastName: 'Parr'
861 | , heroName: 'Mr. Incredible'
862 | , superPower: 'strength'
863 | };
864 |
865 | // dobrze
866 | var hero = {
867 | firstName: 'Bob',
868 | lastName: 'Parr',
869 | heroName: 'Mr. Incredible',
870 | superPower: 'strength'
871 | };
872 | ```
873 |
874 | - **Nie** dodawaj przecinka po ostatnim elemencie w tablicy. Może to wywołać błędy w starszych wersjach IE. W niektórych implementacjach ES3 powiększy to również tablicę o jeden niezidentyfikowany element - ten błąd nie dotyczy ES5 ([źródło](http://es5.github.io/#D)):
875 |
876 | > 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.
877 |
878 | ```javascript
879 | // źle
880 | var hero = {
881 | firstName: 'Kevin',
882 | lastName: 'Flynn',
883 | };
884 |
885 | var heroes = [
886 | 'Batman',
887 | 'Superman',
888 | ];
889 |
890 | // dobrze
891 | var hero = {
892 | firstName: 'Kevin',
893 | lastName: 'Flynn'
894 | };
895 |
896 | var heroes = [
897 | 'Batman',
898 | 'Superman'
899 | ];
900 | ```
901 |
902 | **[⬆ do góry](#table-of-contents)**
903 |
904 |
905 | ## Średniki
906 |
907 | - **Tak.**
908 |
909 | ```javascript
910 | // źle
911 | (function() {
912 | var name = 'Skywalker'
913 | return name
914 | })()
915 |
916 | // dobrze
917 | (function() {
918 | var name = 'Skywalker';
919 | return name;
920 | })();
921 |
922 | // dobrze (taki zapis zapewnia poprawne działanie funkcji przed i po minimalizacji kodu przy pomocy np. Grunta, concata itp.)
923 | ;(function() {
924 | var name = 'Skywalker';
925 | return name;
926 | })();
927 | ```
928 |
929 | [Więcej na ten temat](http://stackoverflow.com/a/7365214/1712802).
930 |
931 | **[⬆ do góry](#table-of-contents)**
932 |
933 |
934 | ## Rzutowania i korekcje typów
935 |
936 | - Jeżeli to konieczne, dokonuj korekcji typu na początku wyrażenia.
937 | - Rzutowanie Stringów:
938 |
939 | ```javascript
940 | // => this.reviewScore = 9;
941 |
942 | // źle
943 | var totalScore = this.reviewScore + '';
944 |
945 | // dobrze
946 | var totalScore = '' + this.reviewScore;
947 |
948 | // źle
949 | var totalScore = '' + this.reviewScore + ' total score';
950 |
951 | // dobrze
952 | var totalScore = this.reviewScore + ' total score';
953 | ```
954 |
955 | - Rzutowanie liczb. Używaj `parseInt` do zmiennych numerycznych i zawsze podawaj podstawę systemu liczbowego użytego podczas rzutowania.
956 |
957 | ```javascript
958 | var inputValue = '4';
959 |
960 | // źle
961 | var val = new Number(inputValue);
962 |
963 | // źle
964 | var val = +inputValue;
965 |
966 | // źle
967 | var val = inputValue >> 0;
968 |
969 | // źle
970 | var val = parseInt(inputValue);
971 |
972 | // dobrze
973 | var val = Number(inputValue);
974 |
975 | // dobrze
976 | var val = parseInt(inputValue, 10);
977 | ```
978 |
979 | - Jeżeli tworzysz akurat maszynę kwantową i niestety `parseInt` nie spełnia Twoich oczekiwań pod względem optymalizacji, posłuż się przesunięciem bitowym. [Są ku temu powody](http://jsperf.com/coercion-vs-casting/3), ale koniecznie pozostaw komentarz czemu to zrobiłeś.
980 |
981 | ```javascript
982 | // dobrze
983 | /**
984 | * parseInt sprawiało, że program lagował.
985 | * Przesunięcie bitowe Stringa koryguje
986 | * typ zmiennej i zachowuje szybkość działania.
987 | */
988 | var val = inputValue >> 0;
989 | ```
990 |
991 | - **Note:** Uważaj z rzutowaniem poprzez przesunięcie bitowe, jeżeli nie masz doświadczenia. Liczby przedstawione są w systemie jako [wartości 64-bitowe](http://es5.github.io/#x4.3.19), ale przesunięcia w JavaScripcie zwracają zawsze 32-bitową liczbę ([źródło](http://es5.github.io/#x11.7)). Przesunięcia mogą przez to zachowywać się w dziwny sposób na liczbach przekraczających 32-bity ( [Dyskusja na temat](https://github.com/airbnb/javascript/issues/109) ). Największa liczba 32-bitowa to 2,147,483,647. Przykładowe przesunięcia i ich wyniki:
992 |
993 | ```javascript
994 | 2147483647 >> 0 //=> 2147483647
995 | 2147483648 >> 0 //=> -2147483648
996 | 2147483649 >> 0 //=> -2147483647
997 | ```
998 |
999 | - Rzutowanie Booleanów:
1000 |
1001 | ```javascript
1002 | var age = 0;
1003 |
1004 | // źle
1005 | var hasAge = new Boolean(age);
1006 |
1007 | // dobrze
1008 | var hasAge = Boolean(age);
1009 |
1010 | // dobrze
1011 | var hasAge = !!age;
1012 | ```
1013 |
1014 | **[⬆ do góry](#table-of-contents)**
1015 |
1016 |
1017 | ## Nazwy zmiennych i funkcji
1018 |
1019 | - Unikaj jednoznakowych nazw. Staraj się w nazwie zawrzeć skrócony opis funkcjonalności tworzonej funkcji lub zmiennej.
1020 |
1021 | ```javascript
1022 | // źle
1023 | function q() {
1024 | // ...kod...
1025 | }
1026 |
1027 | // dobrze
1028 | function query() {
1029 | // ..kod..
1030 | }
1031 | ```
1032 |
1033 | - Używaj konwencji camelCase podczas nazywania zmiennych, funkcji i obiektów.
1034 |
1035 | ```javascript
1036 | // bad
1037 | var OBJEcttsssss = {};
1038 | var this_is_my_object = {};
1039 | function c() {}
1040 | var u = new user({
1041 | name: 'Bob Parr'
1042 | });
1043 |
1044 | // good
1045 | var thisIsMyObject = {};
1046 | function thisIsMyFunction() {}
1047 | var user = new User({
1048 | name: 'Bob Parr'
1049 | });
1050 | ```
1051 |
1052 | - Używaj konwencji PascalCase nadając nazwy konstruktorom i klasom.
1053 |
1054 | ```javascript
1055 | // źle
1056 | function user(options) {
1057 | this.name = options.name;
1058 | }
1059 |
1060 | var bad = new user({
1061 | name: 'nope'
1062 | });
1063 |
1064 | // dobrze
1065 | function User(options) {
1066 | this.name = options.name;
1067 | }
1068 |
1069 | var good = new User({
1070 | name: 'yup'
1071 | });
1072 | ```
1073 |
1074 | - Zmienne prywatne oznaczaj podkreśleniem `_`.
1075 |
1076 | ```javascript
1077 | // źle
1078 | this.__firstName__ = 'Panda';
1079 | this.firstName_ = 'Panda';
1080 |
1081 | // dobrze
1082 | this._firstName = 'Panda';
1083 | ```
1084 |
1085 | - Zapisuj referencję do zmiennej `this` jako `_this`.
1086 |
1087 | ```javascript
1088 | // źle
1089 | function() {
1090 | var self = this;
1091 | return function() {
1092 | console.log(self);
1093 | };
1094 | }
1095 |
1096 | // źle
1097 | function() {
1098 | var that = this;
1099 | return function() {
1100 | console.log(that);
1101 | };
1102 | }
1103 |
1104 | // dobrze
1105 | function() {
1106 | var _this = this;
1107 | return function() {
1108 | console.log(_this);
1109 | };
1110 | }
1111 | ```
1112 |
1113 | - Nazywaj swoje funkcje, nawet jeżeli zapisujesz je do zmiennych. Pomaga to przy debugowaniu.
1114 |
1115 | ```javascript
1116 | // źle
1117 | var log = function(msg) {
1118 | console.log(msg);
1119 | };
1120 |
1121 | // dobrze
1122 | var log = function log(msg) {
1123 | console.log(msg);
1124 | };
1125 | ```
1126 |
1127 | - **Note:** IE8 i starsze wersje mogą się trochę dziwnie zachowywać, jeżeli zastosujesz powyższą zasadę. Więcej na temat [http://kangax.github.io/nfe/](http://kangax.github.io/nfe/).
1128 |
1129 | **[⬆ do góry](#table-of-contents)**
1130 |
1131 |
1132 | ## Gettery i settery
1133 |
1134 | - Akcesory nie są wymagane przy dostępie do parametrów obiektów.
1135 | - Jeżeli tworzysz akcesory używaj formatu getVal() i setVal('hello').
1136 |
1137 | ```javascript
1138 | // źle
1139 | dragon.age();
1140 |
1141 | // dobrze
1142 | dragon.getAge();
1143 |
1144 | // źle
1145 | dragon.age(25);
1146 |
1147 | // dobrze
1148 | dragon.setAge(25);
1149 | ```
1150 |
1151 | - Jeżeli zmienna do której się odnosisz to boolean, używaj isVal() lub hasVal().
1152 |
1153 | ```javascript
1154 | // źle
1155 | if (!dragon.age()) {
1156 | return false;
1157 | }
1158 |
1159 | // dobrze
1160 | if (!dragon.hasAge()) {
1161 | return false;
1162 | }
1163 | ```
1164 |
1165 | - get() i set() są w porządku, o ile używasz ich w czytelny sposób.
1166 |
1167 | ```javascript
1168 | function Jedi(options) {
1169 | options || (options = {});
1170 | var lightsaber = options.lightsaber || 'blue';
1171 | this.set('lightsaber', lightsaber);
1172 | }
1173 |
1174 | Jedi.prototype.set = function(key, val) {
1175 | this[key] = val;
1176 | };
1177 |
1178 | Jedi.prototype.get = function(key) {
1179 | return this[key];
1180 | };
1181 | ```
1182 |
1183 | **[⬆ do góry](#table-of-contents)**
1184 |
1185 |
1186 | ## Konstruktory
1187 |
1188 | - Zamiast nadpisywać `prototype` nowym obiektem, dodawaj do niego pojedyncze metody. Nadpisywanie `prototype` sprawia, że dziedziczenie staje się niemożliwe, a prototypowanie traci swój sens.
1189 |
1190 | ```javascript
1191 | function Jedi() {
1192 | console.log('new jedi');
1193 | }
1194 |
1195 | // źle
1196 | Jedi.prototype = {
1197 | fight: function fight() {
1198 | console.log('fighting');
1199 | },
1200 |
1201 | block: function block() {
1202 | console.log('blocking');
1203 | }
1204 | };
1205 |
1206 | // dobrze
1207 | Jedi.prototype.fight = function fight() {
1208 | console.log('fighting');
1209 | };
1210 |
1211 | Jedi.prototype.block = function block() {
1212 | console.log('blocking');
1213 | };
1214 | ```
1215 |
1216 | - Zwracanie na końcu metod zmiennej `this` umożliwia łączenie metod w łańcuchy.
1217 |
1218 | ```javascript
1219 | // źle
1220 | Jedi.prototype.jump = function() {
1221 | this.jumping = true;
1222 | return true;
1223 | };
1224 |
1225 | Jedi.prototype.setHeight = function(height) {
1226 | this.height = height;
1227 | };
1228 |
1229 | var luke = new Jedi();
1230 | luke.jump(); // => true
1231 | luke.setHeight(20); // => undefined
1232 |
1233 | // dobrze
1234 | Jedi.prototype.jump = function() {
1235 | this.jumping = true;
1236 | return this;
1237 | };
1238 |
1239 | Jedi.prototype.setHeight = function(height) {
1240 | this.height = height;
1241 | return this;
1242 | };
1243 |
1244 | var luke = new Jedi();
1245 |
1246 | luke.jump()
1247 | .setHeight(20);
1248 | ```
1249 |
1250 |
1251 | - Tworzenie własnej wersji konwertera toString() jest ok, jednak upewnij się, że Twoja metoda będzie działać w odpowiedni sposób i nie spowoduje bałaganu w kodzie.
1252 |
1253 | ```javascript
1254 | function Jedi(options) {
1255 | options || (options = {});
1256 | this.name = options.name || 'no name';
1257 | }
1258 |
1259 | Jedi.prototype.getName = function getName() {
1260 | return this.name;
1261 | };
1262 |
1263 | Jedi.prototype.toString = function toString() {
1264 | return 'Jedi - ' + this.getName();
1265 | };
1266 | ```
1267 |
1268 | **[⬆ do góry](#table-of-contents)**
1269 |
1270 |
1271 | ## Zdarzenia
1272 |
1273 | - Wywołując zdarzenie w aplikacji, utwórz nowy obiekt dla parametrów zdarzenia i dopiero w nim dodaj zmienne, które chcesz wysłać. Dzięki temu kolejni programiści aplikacji będą mogli dodawać własne wartości do zdarzenia, bez obaw, że nadpiszą Twoje zmienne. Przykładowo:
1274 |
1275 | ```js
1276 | // źle
1277 | $(this).trigger('listingUpdated', listing.id);
1278 |
1279 | ...
1280 |
1281 | $(this).on('listingUpdated', function(e, listingId) {
1282 | // zrób coś z listingId
1283 | });
1284 | ```
1285 |
1286 | Zamiast tego lepiej jest używać tej postaci:
1287 |
1288 | ```js
1289 | // dobrze
1290 | $(this).trigger('listingUpdated', { listingId : listing.id });
1291 |
1292 | ...
1293 |
1294 | $(this).on('listingUpdated', function(e, data) {
1295 | // zrób coś z data.listingId
1296 | });
1297 | ```
1298 |
1299 | **[⬆ do góry](#table-of-contents)**
1300 |
1301 |
1302 | ## Moduły
1303 |
1304 | - Deklarację modułu rozpoczynaj znakiem `!`. Zapewnia to poprawne działanie modułu w każdych warunkach, również po połączeniu skryptu z plikiem w którym, przykładowo, brakuje średnika na końcu innego modułu. [Wytłumaczenie](https://github.com/airbnb/javascript/issues/44#issuecomment-13063933).
1305 | - Pliki nazywaj stosując sposób zapisu camelCase. Moduły powinny znajdować się w plikach o odpowiadającej im nazwie, w odpowiadającym im folderom. Każdy moduł powinien również posiadać jedną, unikalną, globalną referencję - jeżeli jest ona potrzebna.
1306 | - W modułach zawsze dodawaj metodę `noConflict()`, która odrzuca moduł i nadpisuje go innym, istniejącym w aplikacji odpowiednikiem.
1307 | - Zawsze dodawaj 'use strict;' w nagłówkach swoich modułów.
1308 |
1309 | ```javascript
1310 | // fancyInput/fancyInput.js
1311 |
1312 | !function(global) {
1313 | 'use strict';
1314 |
1315 | var previousFancyInput = global.FancyInput;
1316 |
1317 | function FancyInput(options) {
1318 | this.options = options || {};
1319 | }
1320 |
1321 | FancyInput.noConflict = function noConflict() {
1322 | global.FancyInput = previousFancyInput;
1323 | return FancyInput;
1324 | };
1325 |
1326 | global.FancyInput = FancyInput;
1327 | }(this);
1328 | ```
1329 |
1330 | **[⬆ do góry](#table-of-contents)**
1331 |
1332 |
1333 | ## jQuery
1334 |
1335 | - Nazwy zmiennych utworzonych przy pomocy jQuery rozpoczynaj znakiem dolara `$`.
1336 |
1337 | ```javascript
1338 | // źle
1339 | var sidebar = $('.sidebar');
1340 |
1341 | // dobrze
1342 | var $sidebar = $('.sidebar');
1343 | ```
1344 |
1345 | - Selektory jQuery bardzo często obciążają aplikację, ponieważ przeszukują struktury DOM w poszukiwaniu odpowiednich elementów. Aby zoptymalizować proces wyszukiwania, używaj wyników selektorów zapisanych w zmiennych, zamiast wywoływać ponownie metody jQuery.
1346 |
1347 | ```javascript
1348 | // źle
1349 | function setSidebar() {
1350 | $('.sidebar').hide();
1351 |
1352 | // ...kod...
1353 |
1354 | $('.sidebar').css({
1355 | 'background-color': 'pink'
1356 | });
1357 | }
1358 |
1359 | // dobrze
1360 | function setSidebar() {
1361 | var $sidebar = $('.sidebar');
1362 | $sidebar.hide();
1363 |
1364 | // ...kod...
1365 |
1366 | $sidebar.css({
1367 | 'background-color': 'pink'
1368 | });
1369 | }
1370 | ```
1371 |
1372 | - Ograniczaj zakres poszukiwań selektora jQuery przy pomocy elementów dziedziczących i dziedziczonych, tak bardzo jak tylko to możliwe, przykładowo: `$('.sidebar ul')` lub rodzic > dziecko: `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
1373 | - Używaj metody find() tylko na selektorach zapisanych wcześniej w zmiennych. W pozostałych przypadkach łącz całe wyrażenia w jeden selektor jQuery.
1374 |
1375 | ```javascript
1376 | // źle
1377 | $('ul', '.sidebar').hide();
1378 |
1379 | // źle
1380 | $('.sidebar').find('ul').hide();
1381 |
1382 | // dobrze
1383 | $('.sidebar ul').hide();
1384 |
1385 | // dobrze
1386 | $('.sidebar > ul').hide();
1387 |
1388 | // dobrze
1389 | $sidebar.find('ul').hide();
1390 | ```
1391 |
1392 | **[⬆ do góry](#table-of-contents)**
1393 |
1394 |
1395 | ## Standard ECMAScript 5
1396 |
1397 | - Informacje dotyczące standardu: [Kangax](https://twitter.com/kangax/) oraz [tabele kompatybilności](http://kangax.github.com/es5-compat-table/)
1398 |
1399 | **[⬆ do góry](#table-of-contents)**
1400 |
1401 |
1402 | ## Testowanie
1403 |
1404 | - **No raczej, nie inaczej.**
1405 |
1406 | ```javascript
1407 | function() {
1408 | return true;
1409 | }
1410 | ```
1411 |
1412 | **[⬆ do góry](#table-of-contents)**
1413 |
1414 |
1415 | ## Wydajność (wszystkie artykuły w j. angielskim)
1416 |
1417 | - [On Layout & Web Performance](http://kellegous.com/j/2013/01/26/layout-performance/)
1418 | - [String vs Array Concat](http://jsperf.com/string-vs-array-concat/2)
1419 | - [Try/Catch Cost In a Loop](http://jsperf.com/try-catch-in-loop-cost)
1420 | - [Bang Function](http://jsperf.com/bang-function)
1421 | - [jQuery Find vs Context, Selector](http://jsperf.com/jquery-find-vs-context-sel/13)
1422 | - [innerHTML vs textContent for script text](http://jsperf.com/innerhtml-vs-textcontent-for-script-text)
1423 | - [Long String Concatenation](http://jsperf.com/ya-string-concat)
1424 | - Loading...
1425 |
1426 | **[⬆ do góry](#table-of-contents)**
1427 |
1428 |
1429 | ## Więcej do czytania ( również po angielsku )
1430 |
1431 |
1432 | **To koniecznie**
1433 |
1434 | - [Annotated ECMAScript 5.1](http://es5.github.com/)
1435 |
1436 | **Narzędzia do formatowania**
1437 |
1438 | - Upiększacze kodu
1439 | + [JSHint](http://www.jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/jshintrc)
1440 | + [JSCS](https://github.com/jscs-dev/node-jscs) - [Airbnb Style Preset](https://github.com/jscs-dev/node-jscs/blob/master/presets/airbnb.json)
1441 |
1442 | **Inne, duże poradniki dotyczące formatowania kodu**
1443 |
1444 | - [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml)
1445 | - [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
1446 | - [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwldrn/idiomatic.js/)
1447 |
1448 | **Pojedyncze artykuły i mniej popularne formatowania kodu**
1449 |
1450 | - [Naming this in nested functions](https://gist.github.com/4135065) - Christian Johansen
1451 | - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen
1452 | - [Popular JavaScript Coding Conventions on Github](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
1453 | - [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
1454 |
1455 | **Poza tym warto również zerknąć na to**
1456 |
1457 | - [Understanding JavaScript Closures](http://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
1458 | - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
1459 | - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
1460 | - [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
1461 |
1462 | **Książki**
1463 |
1464 | - [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
1465 | - [JavaScript Patterns](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
1466 | - [Pro JavaScript Design Patterns](http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
1467 | - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
1468 | - [Maintainable JavaScript](http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
1469 | - [JavaScript Web Applications](http://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
1470 | - [Pro JavaScript Techniques](http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
1471 | - [Smashing Node.js: JavaScript Everywhere](http://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
1472 | - [Secrets of the JavaScript Ninja](http://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
1473 | - [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
1474 | - [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
1475 | - [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon
1476 | - [Third Party JavaScript](http://manning.com/vinegar/) - Ben Vinegar and Anton Kovalyov
1477 |
1478 | **Blogi**
1479 |
1480 | - [DailyJS](http://dailyjs.com/)
1481 | - [JavaScript Weekly](http://javascriptweekly.com/)
1482 | - [JavaScript, JavaScript...](http://javascriptweblog.wordpress.com/)
1483 | - [Bocoup Weblog](http://weblog.bocoup.com/)
1484 | - [Adequately Good](http://www.adequatelygood.com/)
1485 | - [NCZOnline](http://www.nczonline.net/)
1486 | - [Perfection Kills](http://perfectionkills.com/)
1487 | - [Ben Alman](http://benalman.com/)
1488 | - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
1489 | - [Dustin Diaz](http://dustindiaz.com/)
1490 | - [nettuts](http://net.tutsplus.com/?s=javascript)
1491 |
1492 | **[⬆ do góry](#table-of-contents)**
1493 |
1494 | ## Kto właściwie z tego korzysta w praktyce
1495 |
1496 | Oto lista organizacji, które używały lub wciąż używają tego sposobu zapisu JavaScriptu. Jeżeli chcesz niej się dopisać stwórz osobny pull request, a my zajmiemy sie resztą.
1497 |
1498 | - **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript)
1499 | - **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript)
1500 | - **American Insitutes for Research**: [AIRAST/javascript](https://github.com/AIRAST/javascript)
1501 | - **Avalara**: [avalara/javascript](https://github.com/avalara/javascript)
1502 | - **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide)
1503 | - **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript)
1504 | - **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript)
1505 | - **Evernote**: [evernote/javascript-style-guide](https://github.com/evernote/javascript-style-guide)
1506 | - **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript)
1507 | - **Gawker Media**: [gawkermedia/javascript](https://github.com/gawkermedia/javascript)
1508 | - **GeneralElectric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript)
1509 | - **GoodData**: [gooddata/gdc-js-style](https://github.com/gooddata/gdc-js-style)
1510 | - **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript)
1511 | - **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript)
1512 | - **InfoJobs**: [InfoJobs/JavaScript-Style-Guide](https://github.com/InfoJobs/JavaScript-Style-Guide)
1513 | - **Intent Media**: [intentmedia/javascript](https://github.com/intentmedia/javascript)
1514 | - **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript)
1515 | - **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript)
1516 | - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript)
1517 | - **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript)
1518 | - **Muber**: [muber/javascript](https://github.com/muber/javascript)
1519 | - **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript)
1520 | - **National Park Service**: [nationalparkservice/javascript](https://github.com/nationalparkservice/javascript)
1521 | - **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript)
1522 | - **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript)
1523 | - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide)
1524 | - **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript)
1525 | - **REI**: [reidev/js-style-guide](https://github.com/reidev/js-style-guide)
1526 | - **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide)
1527 | - **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
1528 | - **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
1529 | - **Target**: [target/javascript](https://github.com/target/javascript)
1530 | - **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
1531 | - **Userify**: [userify/javascript](https://github.com/userify/javascript)
1532 | - **VoxFeed**: [VoxFeed/javascript-style-guide](https://github.com/VoxFeed/javascript-style-guide)
1533 | - **Weggo**: [Weggo/javascript](https://github.com/Weggo/javascript)
1534 | - **Zillow**: [zillow/javascript](https://github.com/zillow/javascript)
1535 | - **ZocDoc**: [ZocDoc/javascript](https://github.com/ZocDoc/javascript)
1536 |
1537 | ## Tłumaczenia
1538 |
1539 | Ten poradnik jest dostępny w wielu różnych językach:
1540 |
1541 | - :en: **Angielski**: [airbnb/javascript](https://github.com/airbnb/javascript)
1542 | - :de: **Niemiecki**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
1543 | - :jp: **Japoński**: [mitsuruog/javacript-style-guide](https://github.com/mitsuruog/javacript-style-guide)
1544 | - :br: **Portugalski**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide)
1545 | - :cn: **Chiński**: [adamlu/javascript-style-guide](https://github.com/adamlu/javascript-style-guide)
1546 | - :es: **Hiszpański**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide)
1547 | - :kr: **Koreański**: [tipjs/javascript-style-guide](https://github.com/tipjs/javascript-style-guide)
1548 | - :fr: **Francuzki**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
1549 | - :ru: **Rosyjski**: [uprock/javascript](https://github.com/uprock/javascript)
1550 | - :bg: **Bułgarski**: [borislavvv/javascript](https://github.com/borislavvv/javascript)
1551 | -  **Kataloński**: [fpmweb/javascript-style-guide](https://github.com/fpmweb/javascript-style-guide)
1552 | - :pl: **Polski**: [mjurczyk/javascript](https://github.com/mjurczyk/javascript)
1553 |
1554 | ## Poradnik do poradnika tego poradnika
1555 |
1556 | - [Dokumentacja](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide)
1557 |
1558 | ## Pogadaj z nami o JavaScripcie
1559 |
1560 | [](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
1561 |
1562 | - Czat dostępny na [gitter](https://gitter.im/airbnb/javascript).
1563 |
1564 | ## Współtwórcy
1565 |
1566 | - [Zobacz listę](https://github.com/airbnb/javascript/graphs/contributors)
1567 |
1568 |
1569 | ## Licencja
1570 |
1571 | (The MIT License)
1572 |
1573 | Copyright (c) 2014 Airbnb
1574 |
1575 | Permission is hereby granted, free of charge, to any person obtaining
1576 | a copy of this software and associated documentation files (the
1577 | 'Software'), to deal in the Software without restriction, including
1578 | without limitation the rights to use, copy, modify, merge, publish,
1579 | distribute, sublicense, and/or sell copies of the Software, and to
1580 | permit persons to whom the Software is furnished to do so, subject to
1581 | the following conditions:
1582 |
1583 | The above copyright notice and this permission notice shall be
1584 | included in all copies or substantial portions of the Software.
1585 |
1586 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
1587 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1588 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1589 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1590 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1591 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1592 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1593 |
1594 | **[⬆ do góry](#table-of-contents)**
1595 |
1596 | # };
1597 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------