├── 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 = ''; 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 | - ![ScreenShot](https://raw.githubusercontent.com/fpmweb/javascript-style-guide/master/img/catala.png) **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 | [![Gitter](https://badges.gitter.im/Join Chat.svg)](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 | --------------------------------------------------------------------------------