Skip to content

Latest commit

 

History

History

bg_BG

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Принципи на консистентно и идиоматично писане на JavaScript

Това е "жив" документ и нови идеи за подобряване на кода са винаги добре дошли. Допринесете: fork, clone, branch, commit, push, pull request.

Целият код във всяка кодова база трябва да изглежда като писано от един човек, няма значение колко души са допринесли.

Последващия списък изтъква практиките, които използвам в всичкия ми код, на който съм оригинален автор; участия в проекти, които съм създал трябва да следват тези напътствия.

Нямам намерение да налагам моите предпочитания за стил на кода или проекти на други хора; ако има наличие на съществуващ общ стил, той трябва да се спазва.

"Спорове за стилове са безсмислени. Трябва да има ръководство за стила и трябва да го спазвате"

Rebecca Murphey

 

"Част от това да си добър ръководител на един успешен проект е да осъзнаете, че писането на код за вас е лоша идея. Ако хиляди души използват вашия код, тогава пишете кода ви максилнално ясно, а не по вашето лично предпочитание."

Idan Gazit

Translations

Важни, Не-Идиоматични Неща:

Инструменти за Качество на Кода, Ресурси & Референции

Станете Умни

Последващото трябва да се вземе под внимание 1) недовършено, и 2) ИЗИСКВА СЕ ЧЕТЕНЕ. Не винаги съм съгласен със стила написан от авторите по-долу, но едно нещо е сигурно: Те са консистентни. Нещо повече, това са авторитети на езика.

Процес на компилация и деплойване

Проектите винаги трябва да включат някои общи средства, чрез които източникът да бъде свързан, тестван и компресиран при подготовка за производствена употреба. За тази задача, grunt на Бен Алман е най-добрата от всички официални заместители на папката "kits/" в това хранилище.

Тестова база

Проектите трябва да включват някаква форма на единица, референция, имплементация или функционално тестване. Демострационни случаи на употреба НЕ СЕ КВАЛИФИЦИРАТ като "тестове". По-долу има списък със тестови рамки, нито една от които не е одобрена повече от другата.

Съдържание


Предговор

Следващите раздели посочват едно разумно ръководство на стил за съвременна разработка на JavaScript и не е предназначен за норматив. Най-важната част е закона за постоянност на стила на кода. Каквото и да изберете като стил за вашия проект, трябва да се счита за закон. Използвайте този документ като напътствие на вашето отдаване към проекта ви за консистентност на стила на кода, четимост и поддържане.

Манифест на идиоматичния стил

  1. Празно пространство
  • Никога не смесвайте спейсове и табове.
  • Когато започнете един проект, преди да почнете да пишете какъвто и да е код, изберете между меки отсъпи (интервали) или реални табулации, считайте го за закон
    • За четимост, винаги препоръчвам да зададете размера на отстъпа на вашия редактор на два знака — което означава два интервала или два интервала, представляващи истинска табулация.
  • Винаги работете с включена настройка "покажи скрити", ако редактора ви я поддържа. Предимствата на тази практика са:
    • Усилена консистенция
    • Премахване на интервал в края на реда
    • Премахване на празни редове
    • Комитите и разликите в кода са по-лесни за четене
  • Използвайте Editorconfig когато е възможно. Поддържа повечето IDEs и обработва повечето настройки за празно пространство.
  1. Красив синтаксис

    A. Parens, Braces, Linebreaks А. Скоби, Фигурни Скоби, Пренасяне на редовете

    // if/else/for/while/try винаги имат интервали между тях, къдравите скоби и разделението между секциите са на множество редове
    // това подобрява четимостта
    
    // 2.A.1.1
    // Примери за наистина нечетлив синтаксис
    
    if(condition) doSomething();
    
    while(condition) iterating++;
    
    for(var i=0;i<100;i++) someIterativeFn();
    
    
    // 2.A.1.1
    // Използвайте интервали за да повишите четимостта
    
    if ( condition ) {
      // изрази
    }
    
    while ( condition ) {
      // изрази
    }
    
    for ( var i = 0; i < 100; i++ ) {
      // изрази
    }
    
    // Още по-добре:
    
    var i,
      length = 100;
    
    for ( i = 0; i < length; i++ ) {
      // изрази
    }
    
    // Или...
    
    var i = 0,
      length = 100;
    
    for ( ; i < length; i++ ) {
      // изрази
    }
    
    var prop;
    
    for ( prop in object ) {
      // изрази
    }
    
    
    if ( true ) {
      // изрази
    } else {
      // изрази
    }

    B. Прислояване, Декларации, Функции ( Именувани, Изрази, Конструктори)

    // 2.B.1.1
    // Променливи
    var foo = "bar",
      num = 1,
      undef;
    
    // Литерална нотация:
    var array = [],
      object = {};
    
    
    // 2.B.1.2
    // Използването на само един `var` на всеки обхват (функция) или по един `var` на всяка променлива,
    // повишава четимостта и пази вашия списък на декларации от безредие.
    // Използването по един `var` на всяка променлива можете да контролирате по-добре версиите 
    // и освен това улеснява разместването на редовете.
    // Един `var` на всеки обхват улеснява намирането на недекларирани променливи,
    // които могат да станат подразбиращи се глобални.
    // Изберете по-добрия подход за вашия проект и никога не го смесвайте
    
    // Лош пример
    var foo = "",
      bar = "";
    var qux;
    
    // Добър пример
    var foo = "";
    var bar = "";
    var qux;
    
    // или..
    var foo = "",
      bar = "",
      qux;
    
    // или..
    var // Коментар на тези
    foo = "",
    bar = "",
    quux;
    
    // 2.B.1.3
    // Операторите 'var' винаги трябва да са в началото на техния съответен обxват (функция).
    
    // Лош пример
    function foo() {
    
      // някакви изрази
    
      var bar = "",
        qux;
    }
    
    // Добър пример
    function foo() {
      var bar = "",
        qux;
    
      // всички изрази след декларацията на променливите
    }
    
    // 2.B.1.4
    // 'const' и `let`, от ECMAScript 6, също трябва да са в горната част на техния обхват (блоков).
    
    // Лош пример
    function foo() {
      let foo,
        bar;
      if ( condition ) {
        bar = "";
        // изрази
      }
    }
    // Добър пример
    function foo() {
      let foo;
      if ( condition ) {
        let bar = "";
        // изрази
      }
    }
    // 2.B.2.1
    // Деклариране на именувана функция
    function foo( arg1, argN ) {
    
    }
    
    // Използване 
    foo( arg1, argN );
    
    
    // 2.B.2.2
    // Деклариране на именувана функция
    function square( number ) {
      return number * number;
    }
    
    // Използване
    square( 10 );
    
    // Много измислен стил на подаване на параметри
    function square( number, callback ) {
      callback( number * number );
    }
    
    square( 10, function( square ) {
      // изрази с обратно извикване
    });
    
    
    // 2.B.2.3
    // Функция-Израз
    var square = function( number ) {
      // Върнете нещо важно и релевантно
      return number * number;
    };
    
    // Функция-Израз с Идентификатор
    // Тази предпочитана форма има добавената стойност
    // и името му ще бъде видимо в стека на функционалните обаждания:
    var factorial = function factorial( number ) {
      if ( number < 2 ) {
        return 1;
      }
    
      return number * factorial( number - 1 );
    };
    
    
    // 2.B.2.4
    // Деклариране на Конструктор
    function FooBar( options ) {
    
      this.options = options;
    }
    
    // Използване
    var fooBar = new FooBar({ a: "alpha" });
    
    fooBar.options;
    // { a: "alpha" }

    C. Изключения, леки отклонения

    // 2.C.1.1
    // Функции с обратно извикване
    foo(function() {
      // Забележете, че няма интервали между първата скоба
      // на изпълненото фунционално извикване и думата "function"
    });
    
    // Функция приемаща масив като параметър, без интервал
    foo([ "alpha", "beta" ]);
    
    // 2.C.1.2
    // Функция приемаща обект като параметър, без интервал
    foo({
      a: "alpha",
      b: "beta"
    });
    
    // Единичен низ като параметър, също без интервал
    foo("bar");
    
    // Съдържание във вътрешни скоби, също без интервал
    if ( !("foo" in obj) ) {
      obj = (obj.bar || defaults).baz;
    }

    D. Консистентността винаги побеждава

    В секции 2.A-2.C, правилата за интервали са изложени като препоръка с по-проста и по-извисена цел: консистентност. Важно е да се отбележи, че предпочитанията за форматиране, такива като "вътрешно пространство", трябва да се считат за незадължителни, но само един стил трябва да съществува из целия код на вашия проект.

    // 2.D.1.1
    
    if (condition) {
      // изрази
    }
    
    while (condition) {
      // изрази
    }
    
    for (var i = 0; i < 100; i++) {
      // изрази
    }
    
    if (true) {
      // изрази
    } else {
      // изрази
    }

    E. Кавички

    Независимо от това дали предпочитате единични или двойни кавички, няма разлика в това как JavaScript ги парсва. Това което АБСОЛЮТНО ТРЯБВА да се наложи е консистентност. Никога не смесвайте кавичките в един и същи проект. Изберете един стил и се придържайте към него.

    F. Край на Редовете и Празни Редове

    Пространствата могат да развалят разликите и да направят промените невъзможни за четене. Помислете да включите "pre-commit" кука, която да премахне автоматично пространството на края на реда и празните пространства на редовете.

  2. Type Checking (Courtesy jQuery Core Style Guidelines)

    A. Типове

    String:

     typeof variable === "string"
    

    Number:

     typeof variable === "number"
    

    Boolean:

     typeof variable === "boolean"
    

    Object:

     typeof variable === "object"
    

    Array:

     Array.isArray( arrayLikeObject )
     (wherever possible)
    

    Node:

     elem.nodeType === 1
    

    null:

     variable === null
    

    null or undefined:

     variable == null
    

    undefined:

    Глобални променливи:

     typeof variable === "undefined"
    

    Локални променливи:

     variable === undefined
    

    Свойства:

     object.prop === undefined
     object.hasOwnProperty( prop )
     "prop" in object
    

    B. Прехвърляне на Типове

    Представете си следното...

    Даден ви е следния HTML:

    <input type="text" id="foo-input" value="1">
    // 3.B.1.1
    
    // `foo` е деклариран със стойност `0` и неговия тип е `number`
    var foo = 0;
    
    // typeof foo;
    // "number"
    ...
    
    // Някъде по-късно във вашия код, трябва да обновите `foo`
    // с нова стойност взета от елемента 'input'
    
    foo = document.getElementById("foo-input").value;
    
    // Ако сега тествате 'typeof foo`, резултатът ще бъде 'string' 
    // Това означава, че ако имате логика, която тества 'foo' като тази:
    if ( foo === 1 ) {
    
      importantTask();
    
    }
    
    // `importantTask()` няма никога да бъде достигнат дори и `foo` да има стойност "1"
    
    // 3.B.1.2
    
    // Можете да избегнете проблеми като използвате умно конвертиране в унарните оператори + и -:
    
    foo = +document.getElementById("foo-input").value;
    //    ^ унарния оператор + ще преобразува десния си операнд в тип 'number'
    
    // typeof foo;
    // "number"
    
    if ( foo === 1 ) {
    
      importantTask();
    
    }
    
    // `importantTask()` ще бъде извикана

    Ето няколко често срещани примера за прехвърляне на типове:

    // 3.B.2.1
    
    var number = 1,
      string = "1",
      bool = false;
    
    number;
    // 1
    
    number + "";
    // "1"
    
    string;
    // "1"
    
    +string;
    // 1
    
    +string++;
    // 1
    
    string;
    // 2
    
    bool;
    // false
    
    +bool;
    // 0
    
    bool + "";
    // "false"
    // 3.B.2.2
    
    var number = 1,
      string = "1",
      bool = true;
    
    string === number;
    // false
    
    string === number + "";
    // true
    
    +string === number;
    // true
    
    bool === number;
    // false
    
    +bool === number;
    // true
    
    bool === string;
    // false
    
    bool === !!string;
    // true
    // 3.B.2.3
    
    var array = [ "a", "b", "c" ];
    
    !!~array.indexOf("a");
    // true
    
    !!~array.indexOf("b");
    // true
    
    !!~array.indexOf("c");
    // true
    
    !!~array.indexOf("d");
    // false
    
    // Забележете, че горните примери може да се считат за "ненужно умни"
    // За предпочитане е очевидния подход да сравнявате върнатата стойност на
    // indexOf, по този начин:
    
    if ( array.indexOf( "a" ) >= 0 ) {
      // ...
    }
    // 3.B.2.4
    
    
    var num = 2.5;
    
    parseInt( num, 10 );
    
    // е съшото като ...
    
    ~~num;
    
    num >> 0;
    
    num >>> 0;
    
    // Във всички случаи резултатът е равен на 2
    
    
    // Помнете, че отрицателните числа ще бъдат обработени различно ...
    
    var neg = -2.5;
    
    parseInt( neg, 10 );
    
    // е същото като...
    
    ~~neg;
    
    neg >> 0;
    
    // Във всички случаи резултатът е равен на -2
    // Въпреки че при...
    
    neg >>> 0;
    
    // Резултата ще е 4294967294
    
    
    
  3. Условна Проверка

    // 4.1.1
    // Проверете дали масивът има дължина,
    // вместо:
    if ( array.length > 0 ) ...
    
    // ...проверявайте за истина, по този начин:
    if ( array.length ) ...
    
    
    // 4.1.2
    // Проверете дали масива е празен,
    // вместо:
    if ( array.length === 0 ) ...
    
    // ...проверявайте за вярност, по този начин:
    if ( !array.length ) ...
    
    
    // 4.1.3
    // Проверете дали низа не е празен,
    // вместо:
    if ( string !== "" ) ...
    
    // ...проверявайте за вярност, по този начин:
    if ( string ) ...
    
    
    // 4.1.4
    // Проверете дали низа _е_ празен,
    // вместо:
    if ( string === "" ) ...
    
    // ...проверявайте дали израдът е неверен, по този начин:
    if ( !string ) ...
    
    
    // 4.1.5
    // Проверете дали тази референция е вярна,
    // вместо:
    if ( foo === true ) ...
    
    // ...проверете, възползвайки се от вградените възможности:
    if ( foo ) ...
    
    
    // 4.1.6
    // Проверете дали тази референция е невярна,
    // вместо:
    if ( foo === false ) ...
    
    // ...проверете, използвайки отрицание
    if ( !foo ) ...
    
    // ...Внимавайте, това важи и за: 0, "", null, undefined, NaN
    // Ако _трябва_ да тествате за булево невярно, тогава използвайте
    
    if ( foo === false ) ...
    
    
    // 4.1.7
    // Когато проверявате дали е null или undefined, но НЕ Е false, "" или 0,
    // вместо това:
    if ( foo === null || foo === undefined ) ...
    
    // ...използвайте оператора ==:
    if ( foo == null ) ...
    
    // Помнете, че използвайки оператора == с `null` важи И ЗА ДВЕТЕ `null` и `undefined`
    // но не `false ', "" или 0
    null == undefined

    ВИНАГИ проверявайте за най-добрия и точен резултат - горното е ръководство, не догма.

    // 4.2.1
    // Преобразуване на типове и бележки за проверяване
    
    // За предпочитане е да използвате `===` вместо `==` (освен ако конкретния случай не изисква слабо типизирана оценка)
    
    // === проверява и типа, т.е.:
    
    "1" === 1;
    // false
    
    // == не проверява типа, т.е.:
    
    "1" == 1;
    // true
    
    
    // 4.2.2
    // Логически изрази, Вярни & Невярни
    
    //  Логически изрази:
    true, false
    
    // Вярни:
    "foo", 1
    
    // Невярни:
    "", 0, null, undefined, NaN, void 0
  4. Стил на Практика

    // 5.1.1
    // Практичен модул
    
    (function( global ) {
      var Module = (function() {
    
        var data = "secret";
    
        return {
          // Логическо свойство
          bool: true,
          // Стойност от тип низ
          string: "a string",
          // Свойство - масив
          array: [ 1, 2, 3, 4 ],
          // Свойство - обект
          object: {
            lang: "bg-BG"
          },
          getData: function() {
            // вземете текущата стойност на променливата `data`
            return data;
          },
          setData: function( value ) {
            // присвоете стойността на `data` и я върнете
            return ( data = value );
          }
        };
      })();
    
      // Други декларации
    
      // добавяме нашия модул към глобалния обект
      global.Module = Module;
    
    })( this );
    // 5.2.1
    // Практичен Конструктор
    
    (function( global ) {
    
      function Ctor( foo ) {
    
        this.foo = foo;
    
        return this;
      }
    
      Ctor.prototype.getFoo = function() {
        return this.foo;
      };
    
      Ctor.prototype.setFoo = function( val ) {
        return ( this.foo = val );
      };
    
    
      // За да извикате конструктора без `new`, можете да направите това:
      var ctor = function( foo ) {
        return new Ctor( foo );
      };
    
    
      // добави нашия конструктор към глобалния обект
      global.ctor = ctor;
    
    })( this );
  5. Наименуване

    A. Вие не сте човешки компилатор/компресор на код, затова не се опитвайте да бъдете такъв.

    Последващия код е пример за лошо именуване:

    // 6.A.1.1
    // Пример за код с лоши имена
    
    function q(s) {
      return document.querySelectorAll(s);
    }
    var i,a=[],els=q("#foo");
    for(i=0;i<els.length;i++){a.push(els[i]);}

    Без съмнение сте писали код като този - дано това приключи днес.

    Сега същото парче логика, но с по-добро, по-смислено именуване (и четима структура):

    // 6.A.2.1
    // Пример на кода с подобрени имена
    
    function query( selector ) {
      return document.querySelectorAll( selector );
    }
    
    var idx = 0,
      elements = [],
      matches = query("#foo"),
      length = matches.length;
    
    for ( ; idx < length; idx++ ) {
      elements.push( matches[ idx ] );
    }

    Още няколко съвета за именуване на променливи::

    // 6.A.3.1
    // Именуване на низове
    
    `dog` is a string
    
    
    // 6.A.3.2
    // Именуване на масиви
    
    `dogs` is an array of `dog` strings
    
    
    // 6.A.3.3
    // Именуване на фукнции, обекти, инстанции, и т.н.
    
    camelCase; function and var declarations
    
    
    // 6.A.3.4
    // Именуване на конструктори, прототипи и т.н.
    PascalCase; constructor function
    
    
    // 6.A.3.5
    // Именуване на регулярни изрази
    
    rDesc = //;
    
    
    // 6.A.3.6
    // Из Ръководство по стила Google Closure Library
    
    functionNamesLikeThis;
    variableNamesLikeThis;
    ConstructorNamesLikeThis;
    EnumNamesLikeThis;
    methodNamesLikeThis;
    SYMBOLIC_CONSTANTS_LIKE_THIS;

    B. Лица на this

    Извън общоизвестните случаи на call и apply, винаги избирайте .bind( this ) или фунционалния му еквивалент, за създаване на дефиниция BoundFunction за по-късно извикване. Създаването на псевдоним е в краен случай, ако други решения не са подходящи.

    // 6.B.1
    function Device( opts ) {
    
      this.value = null;
    
      // Отворете асинхронен поток,
      // това ще се извиква продължително
      stream.read( opts.path, function( data ) {
    
        // Обновете текущата стойност на инстанцията
        // с последната стойност от
        // потока на данни
        this.value = data;
    
      }.bind(this) );
    
      // Ограничете честотата на събитията изпратени от
      // инстанцията на Device
      setInterval(function() {
    
        // Изпращане на събитие
        this.emit("event");
    
      }.bind(this), opts.freq || 100 );
    }
    
    // Просто се преструвайте, че сме наследили EventEmitter ;)

    Когато не е достъпен фукнционалния еквивалент на .bind съществува в много модерни JavaScript библиотеки.

    // 6.B.2
    
    // например lodash/underscore, _.bind()
    function Device( opts ) {
    
      this.value = null;
    
      stream.read( opts.path, _.bind(function( data ) {
    
        this.value = data;
    
      }, this) );
    
      setInterval(_.bind(function() {
    
        this.emit("event");
    
      }, this), opts.freq || 100 );
    }
    
    // например jQuery.proxy
    function Device( opts ) {
    
      this.value = null;
    
      stream.read( opts.path, jQuery.proxy(function( data ) {
    
        this.value = data;
    
      }, this) );
    
      setInterval( jQuery.proxy(function() {
    
        this.emit("event");
    
      }, this), opts.freq || 100 );
    }
    
    // например dojo.hitch
    function Device( opts ) {
    
      this.value = null;
    
      stream.read( opts.path, dojo.hitch( this, function( data ) {
    
        this.value = data;
    
      }) );
    
      setInterval( dojo.hitch( this, function() {
    
        this.emit("event");
    
      }), opts.freq || 100 );
    }

    В краен случай, създайте алиас на this използвайки self като идентификатор. Това е изключително податливо на грешки и трябва да се избягва, когато е възможно.

    // 6.B.3
    
    function Device( opts ) {
      var self = this;
    
      this.value = null;
    
      stream.read( opts.path, function( data ) {
    
        self.value = data;
    
      });
    
      setInterval(function() {
    
        self.emit("event");
    
      }, opts.freq || 100 );
    }

    C. Използване на thisArg

    Няколко прототипни метода вградени в ES 5.1 идват със специалния thisArg, който трябва да се използва когато е възможно

    // 6.C.1
    
    var obj;
    
    obj = { f: "foo", b: "bar", q: "qux" };
    
    Object.keys( obj ).forEach(function( key ) {
    
      // |this| сочи към `obj`
    
      console.log( this[ key ] );
    
    }, obj ); // <-- последния аргумент е `thisArg`
    
    // Ще изпечата...
    
    // "foo"
    // "bar"
    // "qux"

    thisArg може да се използва Array.prototype.every, Array.prototype.forEach, Array.prototype.some, Array.prototype.map, Array.prototype.filter

  6. Разни

    Този раздел ще служи за илюстриране на идеи и концепции, които не трябва да се считат за догма, вместо това съществува за да даде под съмнение практиките в опит да се намери по-добри начини за изпълнение, на често срещани JavaScript задачи.

    A. Използването на switch трябва да се избягва, тъй като съвременния метод за отстраняване на грешки ще скрие повикванията на функции, които го използват.

    Изглежда че последните версии на браузърите Firefox и Chrome имат значителни подобрения в работата на функциите, които използват switch. http://jsperf.com/switch-vs-object-literal-vs-module

    Забележими подобрения могат да се видят също и тук: #13

    // 7.A.1.1
    // Пример на оператора switch
    
    switch( foo ) {
      case "alpha":
        alpha();
        break;
      case "beta":
        beta();
        break;
      default:
        // код по подразбиране
        break;
    }
    
    // 7.A.1.2
    
    // Алтернативен подход, който подкрепя използваемостта и повторната употреба е да
    // се използва обект за съхранение на "случаи" и функция за делегация
    var cases, delegator;
    
    // Примерът връща само с илюстративни цели.
    cases = {
      alpha: function() {
        // изрази
        // връщане
        return [ "Alpha", arguments.length ];
      },
      beta: function() {
        // изрази
        // връщане
        return [ "Beta", arguments.length ];
      },
      _default: function() {
        // изрази
        // връщане
        return [ "Default", arguments.length ];
      }
    };
    
    delegator = function() {
      var args, key, delegate;
    
      // Трансформиране на списъка с аргументите в масив
      args = [].slice.call( arguments );
    
      // Променяне на ключа на случая от аргументите
      key = args.shift();
    
      // Определяне на ключа по подразбиране
      delegate = cases._default;
    
      // Извличане на метода за да делегиране на операция
      if ( cases.hasOwnProperty( key ) ) {
        delegate = cases[ key ];
      }
    
      // Обхватния аргумент може да бъде зададен към нещо специфични,
      // в този случай, |null| ще бъде достатъчно
      return delegate.apply( null, args );
    };
    
    // 7.A.1.3
    // Сложете Апито в 7.A.1.2 да работи:
    delegator( "alpha", 1, 2, 3, 4, 5 );
    // [ "Alpha", 5 ]
    
    // Разбира се, ключовият аргумент на `случая` може да се основава лесно
    // при някакво друго произволно условие.
    var caseKey, someUserInput;
    
    // Вероятно някакво поле на форма?
    someUserInput = 9;
    
    if ( someUserInput > 10 ) {
      caseKey = "alpha";
    } else {
      caseKey = "beta";
    }
    
    // или...
    
    caseKey = someUserInput > 10 ? "alpha" : "beta";
    
    // И тогава...
    
    delegator( caseKey, someUserInput );
    // [ "Beta", 1 ]
    
    // И разбира се...
    
    delegator();
    // [ "Default", 0 ]
    

    B. Ранните връщания подобряват четимостта на кода с незначителна разлика в производителността

    // 7.B.1.1
    // Лош пример:
    function returnLate( foo ) {
      var ret;
    
      if ( foo ) {
        ret = "foo";
      } else {
        ret = "quux";
      }
      return ret;
    }
    
    // Добър пример:
    
    function returnEarly( foo ) {
    
      if ( foo ) {
        return "foo";
      }
      return "quux";
    }
  7. "Родни" и "Чужди" обекти

    Основния принципт тук е:

    Не правете глупости и всичко ще бъде наред.

    За да подсилите тази концепция, моля гледайте последващата презентация:

    “Everything is Permitted: Extending Built-ins” от Андрю Дюпонт (JSConf2011, Портланд, Орегон)

    https://www.youtube.com/watch?v=xL3xCO7CLNM

  8. Коментари

    Едноредов коментар над кода, за който е предназначен

    Многоредови коментари също са добре дошли

    Коментарите в края на реда са забранени!

    Стила JSDoc е добър, но изисква да се инвестира значително време

  9. Код на Един Език

    Програмите трябва да бъдат написани на един език, независимо какъв е той, както се изисква от хората, които поддържат кода.

Приложение

Първа Запетая.

Всеки проект, който се отнася до този документ като основно ръководство за стил, няма да приеме форматирането на кода "първа запетая", освен ако авторът на проекта конкретно не посочи това.


Creative Commons License
Principles of Writing Consistent, Idiomatic JavaScript by Rick Waldron and Contributors is licensed under a Creative Commons Attribution 3.0 Unported License.
Based on a work at github.com/rwldrn/idiomatic.js.