Skip to content

eraycetinay/javascript

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 

Repository files navigation

Airbnb JavaScript Style Guide() {

JavaScript'e daha akıllıca bir yaklaşım

Not: Bu rehber babel-preset-airbnb ile birlikte Babel ya da benzeri bir derleyici kullandığınızı varsayar. Ayrıca tarayıcı uyumluluğu için uygulamalarınızda airbnb-browser-shims veya benzer bir shims/polyfills kurmanız gerekecektir.

Downloads Downloads Gitter

Bu rehbere farklı dillerden de erişilebilir. Çeviri

Diğer Rehberler

İçindekiler

  1. Veri Türleri
  2. Referanslar
  3. Nesneler
  4. Diziler
  5. Destructuring
  6. String
  7. Fonksiyonlar
  8. Arrow Fonksiyonlar
  9. Sınıflar & Constructor
  10. Modüller
  11. Yineleyiciler ve Oluşturucular
  12. Property
  13. Değişkenler
  14. Hoisting
  15. Karşılaştırma Operatörleri
  16. Bloklar
  17. Koşul İfadeleri
  18. Yorumlar
  19. Whitespace
  20. Virgüller
  21. Noktalı Virgüller
  22. Tip Dönüştürme
  23. İsimlendirme
  24. Accessor
  25. Olaylar
  26. jQuery
  27. ECMAScript 5 Uyumluluğu
  28. ECMAScript 6+ (ES 2015+) Özellikleri
  29. Yerleşik Kütüphaneler
  30. Test
  31. Performans
  32. Kaynaklar
  33. Organizasyonlar
  34. Çeviri
  35. Kılavuz Kılavuzu
  36. JavaScript Sohbet Kanalı
  37. Katkıda Bulunanlar
  38. Lisans
  39. Değişiklikler

Veri Türleri

  • 1.1 Birincil: Birincil(İlkel) bir türe eriştiğinizde doğrudan değer ile karşılaşırsınız.

    • string
    • number
    • boolean
    • null
    • undefined
    • symbol
    const foo = 1;
    let bar = foo;
    
    bar = 9;
    
    console.log(foo, bar); // => 1, 9
    • Symbol türünde polyfill stabil çalışmaz. Bu yüzden bu veri türünü desteklemeyen tarayıcı ve benzeri ortamlarda kullanılmamalıdır.

  • 1.2 Bileşik: Bileşik(başvuru) türlerde değere erişmek için referans değerler ile çalışırsınız.

    • object
    • array
    • function
    const foo = [1, 2];
    const bar = foo;
    
    bar[0] = 9;
    
    console.log(foo[0], bar[0]); // => 9, 9

⬆ başa dön

Referanslar

  • 2.1 Tüm referanslarda const kullanın. var kullanmaktan kaçının. eslint: prefer-const, no-const-assign

    Neden? Bu sayede referansların sonradan değiştirilmesi engellenir; olası hataların önüne geçilir, kodun anlaşılabilirliği artar.

    // kötü
    var a = 1;
    var b = 2;
    
    // iyi
    const a = 1;
    const b = 2;

  • 2.2 Eğer referansları yeniden tanımlayacaksanız, var yerine let kullanın. eslint: no-var jscs: disallowVar

    Neden? let block-scope var function-scope'dur.

    // kötü
    var count = 1;
    if (true) {
      count += 1;
    }
    
    // iyi
    let count = 1;
    if (true) {
      count += 1;
    }

  • 2.3 Unutmayın; let ve const'un her ikiside block-scope'dur.

    // const ve let sadece tanımlandıkları yaşam alanında erişilebilir olacaktır.
    {
      let a = 1;
      const b = 1;
    }
    console.log(a); // ReferenceError (Referans Hatası)
    console.log(b); // ReferenceError (Referans Hatası)

⬆ başa dön

Nesneler

  • 3.1 Nesne yaratırken literal sözdizimini kullanın. eslint: no-new-object

    // kötü
    const item = new Object();
    
    // iyi
    const item = {};

  • 3.2 Nesnelerin property isimlerini dinamik şekilde oluştururken, property'leri block içerisinde yaratın.

    Neden? Nesnenin tüm property'lerini aynı yerde tanımlayabilmenizi sağlar.

    function getKey(k) {
      return `a key named ${k}`;
    }
    
    // kötü
    const obj = {
      id: 5,
      name: 'San Francisco',
    };
    obj[getKey('enabled')] = true;
    
    // iyi
    const obj = {
      id: 5,
      name: 'San Francisco',
      [getKey('enabled')]: true,
    };

  • 3.3 Metodlarda shorthand tekniğini kullanın. eslint: object-shorthand jscs: requireEnhancedObjectLiterals

    // kötü
    const atom = {
      value: 1,
    
      addValue: function (value) {
        return atom.value + value;
      },
    };
    
    // iyi
    const atom = {
      value: 1,
    
      addValue(value) {
        return atom.value + value;
      },
    };

  • 3.4 Property'lerde de shorthand tekniğini kullanın. eslint: object-shorthand jscs: requireEnhancedObjectLiterals

    Neden? Hem yazması hem de anlaşılması daha az zaman alır.

    const lukeSkywalker = 'Luke Skywalker';
    
    // kötü
    const obj = {
      lukeSkywalker: lukeSkywalker,
    };
    
    // iyi
    const obj = {
      lukeSkywalker,
    };

  • 3.5 Shorthand property'lerinize nesnenin en başında yer verin.

    Neden? Bu şekilde hangi property'nin shorthand tekniği kullandığını anlamak kolaylaşacaktır.

    const anakinSkywalker = 'Anakin Skywalker';
    const lukeSkywalker = 'Luke Skywalker';
    
    // kötü
    const obj = {
      episodeOne: 1,
      twoJediWalkIntoACantina: 2,
      lukeSkywalker,
      episodeThree: 3,
      mayTheFourth: 4,
      anakinSkywalker,
    };
    
    // iyi
    const obj = {
      lukeSkywalker,
      anakinSkywalker,
      episodeOne: 1,
      twoJediWalkIntoACantina: 2,
      episodeThree: 3,
      mayTheFourth: 4,
    };

  • 3.6 Sadece uygunsuz tanımlarda tırnak kullanın. eslint: quote-props jscs: disallowQuotedKeysInObjects

    Neden? Genelde bu şekilde okunmasının daha kolay olacağını düşünüyoruz. Ayrıca sözdizimi vurgusunun artmasını sağlayacak ve JS motorları tarafından daha kolay optimize edilmesini sağlayacaktır.

    // kötü
    const bad = {
      'foo': 3,
      'bar': 4,
      'data-blah': 5,
    };
    
    // iyi
    const good = {
      foo: 3,
      bar: 4,
      'data-blah': 5,
    };

  • 3.7 hasOwnProperty, propertyIsEnumerable ve isPrototypeOf gibi Object.prototype metodlarını doğrudan kullanmayın.

    Neden? Bu metodlar nesnedeki property'ler tarafından gölgelenebilirler ({ hasOwnProperty: false }) ya da nesne null olabilir (Object.create(null)).

    // kötü
    console.log(object.hasOwnProperty(key));
    
    // iyi
    console.log(Object.prototype.hasOwnProperty.call(object, key));
    
    // çok iyi
    const has = Object.prototype.hasOwnProperty; // scope'da önbelleğe alın.
    /* ya da */
    import has from 'has'; // https://www.npmjs.com/package/has
    // ...
    console.log(has.call(object, key));

  • 3.8 Sığ kopyalamada Object.assign yerine spread operatorünü kullanın. Yeni bir nesne oluştururken dahil etmek istemediğiniz property'ler ile birlikte rest operatorünü kullanın.

    // çok kötü
    const original = { a: 1, b: 2 };
    const copy = Object.assign(original, { c: 3 }); // `original`'i de değiştirir.  ಠ_ಠ
    delete copy.a; // burasıda.
    
    // kötü
    const original = { a: 1, b: 2 };
    const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
    
    // iyi
    const original = { a: 1, b: 2 };
    const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
    
    const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

⬆ başa dön

Diziler

  • 4.1 Dizi yaratırken literal sözdizimini kullanın. eslint: no-array-constructor

    // kötü
    const items = new Array();
    
    // iyi
    const items = [];

  • 4.2 Dizilere yeni elemanları doğrudan eklemek yerine Array#push'u kullanın.

    const someStack = [];
    
    // kötü
    someStack[someStack.length] = 'abracadabra';
    
    // iyi
    someStack.push('abracadabra');

  • 4.3 Dizileri kopyalamak için spread ... operatörünü kullanın.

    // kötü
    const len = items.length;
    const itemsCopy = [];
    let i;
    
    for (i = 0; i < len; i += 1) {
      itemsCopy[i] = items[i];
    }
    
    // iyi
    const itemsCopy = [...items];

  • 4.4 Dizi-benzeri bir nesneyi diziye dönüştürürken Array.from yerine ... spread operatörünü kullanın.

    const foo = document.querySelectorAll('.foo');
    
    // iyi
    const nodes = Array.from(foo);
    
    // çok iyi
    const nodes = [...foo];

  • 4.5 Geçici bir dizi oluşturmamak için dizi elemanlarında map kullanırken spread operatörü ... yerine Array.from kullanın.

    // kötü
    const baz = [...foo].map(bar);
    
    // iyi
    const baz = Array.from(foo, bar);

  • 4.6 Dizi metodlarının callback'lerinde return ifadesini kullanın. Eğer fonksiyon içeriği 8.2 de olduğu gibi tek bir ifadeyi içeriyorsa return kullanılmayabilir. eslint: array-callback-return

    // iyi
    [1, 2, 3].map((x) => {
      const y = x + 1;
      return x * y;
    });
    
    // kötü
    [1, 2, 3].map(x => x + 1);
    
    // kötü - dönen değerin bulunmaması `acc`'nin ilk tekrardan sonra undefined olmasına neden olur
    [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
      const flatten = acc.concat(item);
      acc[index] = flatten;
    });
    
    // iyi
    [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
      const flatten = acc.concat(item);
      acc[index] = flatten;
      return flatten;
    });
    
    // kötü
    inbox.filter((msg) => {
      const { subject, author } = msg;
      if (subject === 'Mockingbird') {
        return author === 'Harper Lee';
      } else {
        return false;
      }
    });
    
    // iyi
    inbox.filter((msg) => {
      const { subject, author } = msg;
      if (subject === 'Mockingbird') {
        return author === 'Harper Lee';
      }
    
      return false;
    });

  • 4.7 Eğer dizide birden fazla satır varsa köşeli parantezleri açtıktan sonra ve kapatmadan önce yeni satıra geçin.

    // kötü
    const arr = [
      [0, 1], [2, 3], [4, 5],
    ];
    
    const objectInArray = [{
      id: 1,
    }, {
      id: 2,
    }];
    
    const numberInArray = [
      1, 2,
    ];
    
    // iyi
    const arr = [[0, 1], [2, 3], [4, 5]];
    
    const objectInArray = [
      {
        id: 1,
      },
      {
        id: 2,
      },
    ];
    
    const numberInArray = [
      1,
      2,
    ];

⬆ başa dön

Destructuring

  • 5.1 Bir nesneden birden fazla property'e erişirken destructuring tekniğini kullanın. eslint: prefer-destructuring jscs: requireObjectDestructuring

    Neden ? Destructuring, property'ler için geçici değişkenler oluşturmanızı önler.

    // kötü
    function getFullName(user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
    
      return `${firstName} ${lastName}`;
    }
    
    // iyi
    function getFullName(user) {
      const { firstName, lastName } = user;
      return `${firstName} ${lastName}`;
    }
    
    // çok iyi
    function getFullName({ firstName, lastName }) {
      return `${firstName} ${lastName}`;
    }

  • 5.3 Birden fazla değer dönmesi durumunda diziler yerine nesneler ile destructuring yapın. jscs: disallowArrayDestructuringReturn

    Neden? Bu sayede zamanla yeni property'ler eklendiğinde ya da sıralama değiştiğinde çağrıyı yapan kod betikleri bozulmayacaktır.

    // kötü
    function processInput(input) {
      // then a miracle occurs
      return [left, right, top, bottom];
    }
    
    // çağrıyı yapan kısım dönen değerlerin sıralamasını dikkate almalıdır
    const [left, __, top] = processInput(input);
    
    // iyi
    function processInput(input) {
      // then a miracle occurs
      return { left, right, top, bottom };
    }
    
    // çağıran bölüm sadece ihtiyacı olanı alır
    const { left, top } = processInput(input);

⬆ başa dön

String

  • 6.1 String'lerde tek tırnak '' kullanın. eslint: quotes jscs: validateQuoteMarks

    // kötü
    const name = "Capt. Janeway";
    
    // kötü - şablon enterpolasyon veya yeni satırlar içerir.
    const name = `Capt. Janeway`;
    
    // iyi
    const name = 'Capt. Janeway';

  • 6.2 100 karakterden uzun string'ler satırlara bölünüp birbirine bağlanmamalıdır.

    Neden? Bölünmüş string'ler ile çalışmak kodun okunabilirliğini düşürür.

    // kötü
    const 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.';
    
    // kötü
    const 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.';
    
    // iyi
    const 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.';

  • 6.3 Programlanabilir string'ler yaratırken string şablonlarını kullanın. eslint: prefer-template template-curly-spacing jscs: requireTemplateStrings

    Neden? String şablonları; kısa, okunabilir, doğru sözdizimi ve string interpolasyon özelliklerine sahip bir kod betiği oluşturabilmenizi sağlar.

    // kötü
    function sayHi(name) {
      return 'How are you, ' + name + '?';
    }
    
    // kötü
    function sayHi(name) {
      return ['How are you, ', name, '?'].join();
    }
    
    // kötü
    function sayHi(name) {
      return `How are you, ${ name }?`;
    }
    
    // iyi
    function sayHi(name) {
      return `How are you, ${name}?`;
    }

  • 6.4 String'lerde asla eval() fonksiyonunu kullanmayın. Bu durum pek çok açığa neden olabilir. eslint: no-eval

  • 6.5 String'lerde gereksiz yere tersbölü karakterlerini kullanmayın. eslint: no-useless-escape

    Neden? Tersbölüler okunabilirliği düşürür ve sadece gerektiğinde kullanılmalıdır.

    // kötü
    const foo = '\'this\' \i\s \"quoted\"';
    
    // iyi
    const foo = '\'this\' is "quoted"';
    const foo = `my name is '${name}'`;

⬆ başa dön

Fonksiyonlar

  • 7.1 Klasik fonksiyon tanımları yerine isimlendirilmiş fonksiyon ifadeleri kullanın. eslint: func-style jscs: disallowFunctionDeclarations

    Neden? Fonksiyon tanımlamaları fazla basite kaçan bir çözümdür. Bu kullanım şekli okunabilirliği ve geliştirilebilirliği düşürür. Eğer fonksiyon kapsamlı ya da dosyadaki diğer betikler ile karışabilecek durumda ise ayrı bir modül haline getirin. Fonksiyon ifadesini açıklayıcı bir şekilde isimlendirmeyi unutmayın. (Tartışma)

    // kötü
    function foo() {
      // ...
    }
    
    // kötü
    const foo = function () {
      // ...
    };
    
    // iyi
    // Açıklayıcı isimlendirmeye değişken üzerinden ulaşılabilir
    const short = function longUniqueMoreDescriptiveLexicalFoo() {
      // ...
    };

  • 7.2 Hemen çağrılan fonksiyonları (Immediately-invoked Function Expressions - IIFE) parantez içine alın. eslint: wrap-iife jscs: requireParenthesesAroundIIFE

    Neden? IIFE, blok bir betiktir. Betiği parantez içine alarak bu durum belirtilir. Not: Modüler bir yapı içerisinde neredeyse hiç IIFE kullanmaya ihtiyacınız olmayacaktır.

    // immediately-invoked function expression (IIFE)
    (function () {
      console.log('Welcome to the Internet. Please follow me.');
    }());

  • 7.3 Fonksiyonları asla fonksiyon harici bir blok (if, while, vb.). içinde tanımlamayın. Bunun yerine fonksiyonu bir değişkene atayın. Tarayıcılar bu tanıma izin verecektir fakat her biri farklı şekilde yorumlayabilir. eslint: no-loop-func

  • 7.4 Not: ECMA-262 block kavramını ifadelerin listesi şeklinde tanımlar. Fonksiyon tanımlamak bir ifade değildir.

    // kötü
    if (currentUser) {
      function test() {
        console.log('Nope.');
      }
    }
    
    // iyi
    let test;
    if (currentUser) {
      test = () => {
        console.log('Yup.');
      };
    }

  • 7.5 Asla bir parametreye arguments adını vermeyin. Bu şekilde bir kullanım her fonksiyonun blok alanında bulunan arguments nesnesinin üzerinde kalacaktır.

    // kötü
    function foo(name, options, arguments) {
      // ...
    }
    
    // iyi
    function foo(name, options, args) {
      // ...
    }

  • 7.6 arguments yerine içeriğe rest ... ile ulaşın. eslint: prefer-rest-params

    Neden? ... ile sadece istenen argümanlara erişebilirsiniz. Ayrıca rest argümanlar dizi-benzeri arguments'in aksine gerçek bir dizidir.

    // kötü
    function concatenateAll() {
      const args = Array.prototype.slice.call(arguments);
      return args.join('');
    }
    
    // iyi
    function concatenateAll(...args) {
      return args.join('');
    }

  • 7.7 Fonksiyon parametrelerini değiştirmek yerine varsayılan parametre sözdizimini kullanın.

    // çok kötü
    function handleThings(opts) {
      // Hayır! Fonksiyon argümanları değiştirilmemeli.
      // Ayrıca, argüman hatalıyken bir nesneye eşitlemek açık oluşturabilir.
      opts = opts || {};
      // ...
    }
    
    // kötü
    function handleThings(opts) {
      if (opts === void 0) {
        opts = {};
      }
      // ...
    }
    
    // iyi
    function handleThings(opts = {}) {
      // ...
    }

  • 7.8 Varsayılan parametrelerin yan etkilerini dikkate alın.

    Neden? Kullanım amacına aykırıdır.

    var b = 1;
    // kötü
    function count(a = b++) {
      console.log(a);
    }
    count();  // 1
    count();  // 2
    count(3); // 3
    count();  // 3

  • 7.9 Varsayılan parametreleri daima en sonda kullanın.

    // kötü
    function handleThings(opts = {}, name) {
      // ...
    }
    
    // iyi
    function handleThings(name, opts = {}) {
      // ...
    }

  • 7.10 Yeni bir fonksiyon yaratmak için asla constructor'ları kullanmayın. eslint: no-new-func

    Neden? Bu şekilde fonksiyon yaratmak güvenlik açıkları oluşturan eval()'e benzer bir durum oluşturur.

    // kötü
    var add = new Function('a', 'b', 'return a + b');
    
    // kötü
    var subtract = Function('a', 'b', 'return a - b');

  • 7.11 Fonksiyonlarda boşlukları doğru şekilde kullanın. eslint: space-before-function-paren space-before-blocks

    Neden? Tutarlılık iyidir ve bu şekilde bir isim eklerken veya silerken boşluk eklemenizede silmenizede gerek kalmaz.

    // kötü
    const f = function(){};
    const g = function (){};
    const h = function() {};
    
    // iyi
    const x = function () {};
    const y = function a() {};

  • 7.12 Asla parametreleri değiştirmeyin. eslint: no-param-reassign

    Neden? Gelen nesneleri değiştirmek çağrıyı yapan betikte beklenmeyen yan etkilere neden olabilir.

    // kötü
    function f1(obj) {
      obj.key = 1;
    }
    
    // iyi
    function f2(obj) {
      const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
    }

  • 7.13 Asla parametreleri yeniden tanımlamayın. eslint: no-param-reassign

    Neden? Parametrelerin yeniden tanımlanması özellikle arguments nesnesine erişirken beklenmeyen davranışlara neden olabilir. Bunun yanında özellikle V8 motorunda optimizasyon sorunlarına neden olabilir.

    // kötü
    function f1(a) {
      a = 1;
      // ...
    }
    
    function f2(a) {
      if (!a) { a = 1; }
      // ...
    }
    
    // iyi
    function f3(a) {
      const b = a || 1;
      // ...
    }
    
    function f4(a = 1) {
      // ...
    }

  • 7.14 Değişken sayıda argüman alabilen (Variadic) fonksiyonlarda spread operatörünü ... kullanmaya özen gösterin. eslint: prefer-spread

    Neden? Daha temiz bir kullanım şeklidir. İçeriği oluşturmanıza ve new ile apply kullanmanıza gerek kalmaz.

    // kötü
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    
    // iyi
    const x = [1, 2, 3, 4, 5];
    console.log(...x);
    
    // kötü
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
    
    // iyi
    new Date(...[2016, 8, 5]);

  • 7.15 Çok satırlı tanımlamalardaki ve çok satırlı çağrılardaki parametreler, bu kılavuzdaki diğer çok satırlı listeler gibi girintili olmalıdır; her öğe bir satırda, son öğe sonunda bir virgül ile birlikte.

    // kötü
    function foo(bar,
                 baz,
                 quux) {
      // ...
    }
    
    // iyi
    function foo(
      bar,
      baz,
      quux,
    ) {
      // ...
    }
    
    // kötü
    console.log(foo,
      bar,
      baz);
    
    // iyi
    console.log(
      foo,
      bar,
      baz,
    );

⬆ başa dön

Arrow Fonksiyonlar

  • 8.1 İsimsiz bir fonksiyon kullanırken (fonksiyon içi bir callback olarak) arrow (ok) fonksiyon notasyonunu kullanın. eslint: prefer-arrow-callback, arrow-spacing jscs: requireArrowFunctions

    Neden? Bu kullanım ihtiyaç duyulduğu gibi, this ile çalışan bir yapı oluşturur ve daha sade bir sözdizimine sahiptir.

    Ne zaman kullanılmamalı? Fonksiyonun karmaşık bir işlevi bulunuyorsa isimlendirilmiş bir fonksiyon ifadesi kullanmalısınız.

    // kötü
    [1, 2, 3].map(function (x) {
      const y = x + 1;
      return x * y;
    });
    
    // iyi
    [1, 2, 3].map((x) => {
      const y = x + 1;
      return x * y;
    });

  • 8.2 Eğer fonksiyon içeriği yan etkisi bulunmayan tek bir ifadeyi geri döndürüyorsa süslü parantez kullanmadan satır içinde ifadeyi kullanın (implicit return). Aksi durumlarda süslü parantez ve return kullanın. eslint: arrow-parens, arrow-body-style jscs: disallowParenthesesAroundArrowParam, requireShorthandArrowFunctions

    Neden? Fonksiyon zincirleri okunabilirliği artırır.

    // kötü
    [1, 2, 3].map(number => {
      const nextNumber = number + 1;
      `A string containing the ${nextNumber}.`;
    });
    
    // iyi
    [1, 2, 3].map(number => `A string containing the ${number}.`);
    
    // iyi
    [1, 2, 3].map((number) => {
      const nextNumber = number + 1;
      return `A string containing the ${nextNumber}.`;
    });
    
    // iyi
    [1, 2, 3].map((number, index) => ({
      [index]: number,
    }));
    
    // Yan etkiler içeren implicit return
    function foo(callback) {
      const val = callback();
      if (val === true) {
        // callback true döndüğünde çalışan betik
      }
    }
    
    let bool = false;
    
    // kötü
    foo(() => bool = true);
    
    // iyi
    foo(() => {
      bool = true;
    });

  • 8.3 İfade birden fazla satır içeriyorsa okunabilirliği artırmak için parantez kullanın.

    Neden? Fonksiyonun nerede başlayıp nerede bittiğini daha net şekilde gösterir.

    // kötü
    ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
        httpMagicObjectWithAVeryLongName,
        httpMethod,
      )
    );
    
    // iyi
    ['get', 'post', 'put'].map(httpMethod => (
      Object.prototype.hasOwnProperty.call(
        httpMagicObjectWithAVeryLongName,
        httpMethod,
      )
    ));

  • 8.4 Fonksiyonunuz tek bir parametre alıyorsa ve süslü parantez kullanmıyorsa, parantez de kullanmayın. Diğer durumlarda sadelik ve tutarlılık için daima parametreleri parantez içine alın. Not: Parantezlerin sürekli kullanımı da kabul edilebilirdir. Bunun için eslint de “always” option kullanın ya da jscs de disallowParenthesesAroundArrowParam'ı dahil etmeyin. eslint: arrow-parens jscs: disallowParenthesesAroundArrowParam

    Neden? Daha az görsel karmaşa.

    // kötü
    [1, 2, 3].map((x) => x * x);
    
    // iyi
    [1, 2, 3].map(x => x * x);
    
    // iyi
    [1, 2, 3].map(number => (
      `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
    ));
    
    // kötü
    [1, 2, 3].map(x => {
      const y = x + 1;
      return x * y;
    });
    
    // iyi
    [1, 2, 3].map((x) => {
      const y = x + 1;
      return x * y;
    });

  • 8.5 Arrow fonksiyonları (=>) yazarken karşılaştırma operatörleri (<=, >=) ile karıştırmamaya dikkat edin. eslint: no-confusing-arrow

    // kötü
    const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
    
    // kötü
    const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
    
    // iyi
    const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
    
    // iyi
    const itemHeight = (item) => {
      const { height, largeSize, smallSize } = item;
      return height > 256 ? largeSize : smallSize;
    };

⬆ başa dön

Sınıflar & Constructor

  • 9.1 Daima class kullanın. Doğrudan prototype manipulasyonundan kaçının.

    Neden? class sözdizimi daha doğru ve kolaydır.

    // kötü
    function Queue(contents = []) {
      this.queue = [...contents];
    }
    Queue.prototype.pop = function () {
      const value = this.queue[0];
      this.queue.splice(0, 1);
      return value;
    };
    
    // iyi
    class Queue {
      constructor(contents = []) {
        this.queue = [...contents];
      }
      pop() {
        const value = this.queue[0];
        this.queue.splice(0, 1);
        return value;
      }
    }

  • 9.2 Kalıtım için extends'i kullanın.

    Neden? Prototip işlevselliğini instanceof'u bozmadan içselleştirmenin yerleşik olarak gelen yöntemidir.

    // kötü
    const inherits = require('inherits');
    function PeekableQueue(contents) {
      Queue.apply(this, contents);
    }
    inherits(PeekableQueue, Queue);
    PeekableQueue.prototype.peek = function () {
      return this.queue[0];
    };
    
    // iyi
    class PeekableQueue extends Queue {
      peek() {
        return this.queue[0];
      }
    }

  • 9.3 Metodlar, metod zincirleri için this return edebilir.

    // kötü
    Jedi.prototype.jump = function () {
      this.jumping = true;
      return true;
    };
    
    Jedi.prototype.setHeight = function (height) {
      this.height = height;
    };
    
    const luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20); // => undefined
    
    // iyi
    class Jedi {
      jump() {
        this.jumping = true;
        return this;
      }
    
      setHeight(height) {
        this.height = height;
        return this;
      }
    }
    
    const luke = new Jedi();
    
    luke.jump()
      .setHeight(20);

  • 9.4 Özel toString() metodları yazılabilir fakat doğru şekilde çalıştığına ve yan etkiler oluşturmadığına emin olunmalıdır.

    class Jedi {
      constructor(options = {}) {
        this.name = options.name || 'no name';
      }
    
      getName() {
        return this.name;
      }
    
      toString() {
        return `Jedi - ${this.getName()}`;
      }
    }

  • 9.5 Eğer bir constructor tanımlanmadıysa sınıflarda varsayılan bir constructor bulunur. Boş bir constructor ya da üst sınıfı temsil eden bir constructor gereksizdir. eslint: no-useless-constructor

    // kötü
    class Jedi {
      constructor() {}
    
      getName() {
        return this.name;
      }
    }
    
    // kötü
    class Rey extends Jedi {
      constructor(...args) {
        super(...args);
      }
    }
    
    // iyi
    class Rey extends Jedi {
      constructor(...args) {
        super(...args);
        this.name = 'Rey';
      }
    }

  • 9.6 Sınıf üyelerini tekrarlamaktan kaçının. eslint: no-dupe-class-members

    Neden? Sınıf üyelerinin tekrar deklare edilmesi durumunda son tekrarlanan üye dikkate alınır.

    // kötü
    class Foo {
      bar() { return 1; }
      bar() { return 2; }
    }
    
    // iyi
    class Foo {
      bar() { return 1; }
    }
    
    // iyi
    class Foo {
      bar() { return 2; }
    }

⬆ başa dön

Modüller

  • 10.1 Standart bir yapıya sahip olmayan modül sistemlerinizde daima (import/export) kullanın. İstediğinizde tercih ettiğiniz modül sistemine (transpile) çevirebilirsiniz.

    Neden? Modüller geleceğin teknolojisidir. Şimdiden kullanmaya başlamalısınız.

    // kötü
    const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    module.exports = AirbnbStyleGuide.es6;
    
    // normal
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    export default AirbnbStyleGuide.es6;
    
    // iyi
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

  • 10.2 Wildcard import'ları kullanmayın.

    Neden? Böylece tek bir default export'unuz bulunacaktır.

    // kötü
    import * as AirbnbStyleGuide from './AirbnbStyleGuide';
    
    // iyi
    import AirbnbStyleGuide from './AirbnbStyleGuide';

  • 10.3 Import üzerinden direkt export etmeyin.

    Neden? Tek satırda kullanmak daha sade gözüksede, import ve export'u farklı satırlara ayırmak daha temiz ve tutarlıdır.

    // kötü
    // filename es6.js
    export { es6 as default } from './AirbnbStyleGuide';
    
    // iyi
    // filename es6.js
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

  • 10.4 Aynı path üzerindeki tüm import'ları aynı yerde yapın. eslint: no-duplicate-imports

    Neden? Aynı path üzerinden farklı konumlarda import kullanmak kodun geliştirilmesini zorlaştıracaktır.

    // kötü
    import foo from 'foo';
    // … diğer import'lar … //
    import { named1, named2 } from 'foo';
    
    // iyi
    import foo, { named1, named2 } from 'foo';
    
    // iyi
    import foo, {
      named1,
      named2,
    } from 'foo';

  • 10.5 Değiştirilebilir binding'leri export etmeyin. eslint: import/no-mutable-exports

    Neden? Değiştirmelerden genel olarak kaçınılmalıdır, özellikle de binding'lerde. Zaman zaman bu teknik görmezden gelinebilir ancak genellikle değişmeyen/sabit değişkenler export edilmelidir.

    // kötü
    let foo = 3;
    export { foo };
    
    // iyi
    const foo = 3;
    export { foo };

  • 10.6 Tek bir export'a sahip modüllerde isimlendirilmiş export yerine default export kullanın. eslint: import/prefer-default-export

    Neden? Tek bir export kullandığınız modüllerde default kullanımı okunabilirliği ve geliştirilebilirliği artırır.

    // bad
    export function foo() {}
    
    // good
    export default function foo() {}

  • 10.7 Tüm import'ları diğer ifadelerin üzerinde kullanın. eslint: import/first

    Neden? import kullanımından doğabilecek aksilikleri önleyecektir.

    // kötü
    import foo from 'foo';
    foo.init();
    
    import bar from 'bar';
    
    // iyi
    import foo from 'foo';
    import bar from 'bar';
    
    foo.init();

  • 10.8 Import'lar tıpkı çok satırlı diziler ve çok satırlı sabitler gibi kullanılmalıdır.

    Neden? Süslü parantezlere sahip bloklar stil rehberinin tamamında aynı yazım kurallarına sahiptir.

    // kötü
    import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
    
    // iyi
    import {
      longNameA,
      longNameB,
      longNameC,
      longNameD,
      longNameE,
    } from 'path';

  • 10.9 Modül import ifadelerinde webpack loader sözdizimini kullanmayın. eslint: import/no-webpack-loader-syntax

    Neden? Webpack sözdizimi module bundler'da importları çoğaltır. Bunun yerine loader sözdizimini webpack.config.js içerisinde kullanın.

    // kötü
    import fooSass from 'css!sass!foo.scss';
    import barCss from 'style!css!bar.css';
    
    // iyi
    import fooSass from 'foo.scss';
    import barCss from 'bar.css';

⬆ başa dön

Yineleyiciler ve Oluşturucular

  • 11.1 Yineleyici (Iterator) kullanmayın. for-in ve for-of gibi döngülerde higher-order fonksiyonları tercih edin. eslint: no-iterator no-restricted-syntax

    Neden? Değerleri return eden sade fonksiyonların kullanılması yan etkileri önler ve bu kullanım şekli en önemli kurallardandır.

    Diziler üzerinde map() / every() / filter() / find() / findIndex() / reduce() / some() kullanın. / Object.keys() / Object.values() / Object.entries() kullanarak nesneler üzerinde çalışabilir ve diziler üretebilirsiniz.

    const numbers = [1, 2, 3, 4, 5];
    
    // kötü
    let sum = 0;
    for (let num of numbers) {
      sum += num;
    }
    sum === 15;
    
    // iyi
    let sum = 0;
    numbers.forEach((num) => {
      sum += num;
    });
    sum === 15;
    
    // çok iyi
    const sum = numbers.reduce((total, num) => total + num, 0);
    sum === 15;
    
    // kötü
    const increasedByOne = [];
    for (let i = 0; i < numbers.length; i++) {
      increasedByOne.push(numbers[i] + 1);
    }
    
    // iyi
    const increasedByOne = [];
    numbers.forEach((num) => {
      increasedByOne.push(num + 1);
    });
    
    // çok iyi
    const increasedByOne = numbers.map(num => num + 1);

  • 11.2 Şimdilik oluşturucu (generator) kullanmayın.

    Neden? ES5'e doğru şekilde transpile edilemezler.

  • 11.3 Eğer oluşturucu kullanmanız gerekiyorsa, ya da önerimizi görmezden gelmek istiyorsanız fonksiyon tanımınızda boşluk karakterini doğru şekilde kullandığınıza emin olun. eslint: generator-star-spacing

    Neden? function ve * kavramsal terimlerdir. *, function için bir niteleyici değildir. function*, function'ın aksine eşsiz bir construct'tır.

    // kötü
    function * foo() {
      // ...
    }
    
    // kötü
    const bar = function * () {
      // ...
    };
    
    // kötü
    const baz = function *() {
      // ...
    };
    
    // kötü
    const quux = function*() {
      // ...
    };
    
    // kötü
    function*foo() {
      // ...
    }
    
    // kötü
    function *foo() {
      // ...
    }
    
    // çok kötü
    function
    *
    foo() {
      // ...
    }
    
    // çok kötü
    const wat = function
    *
    () {
      // ...
    };
    
    // iyi
    function* foo() {
      // ...
    }
    
    // iyi
    const foo = function* () {
      // ...
    };

⬆ başa dön

Property

  • 12.1 Property'lere erişirken nokta notasyonunu kullanın. eslint: dot-notation jscs: requireDotNotation

    const luke = {
      jedi: true,
      age: 28,
    };
    
    // kötü
    const isJedi = luke['jedi'];
    
    // iyi
    const isJedi = luke.jedi;

  • 12.2 Bir değişken ile property'lere erişirken köşeli parantez [] kullanın.

    const luke = {
      jedi: true,
      age: 28,
    };
    
    function getProp(prop) {
      return luke[prop];
    }
    
    const isJedi = getProp('jedi');

  • 12.3 Üstalma hesaplamalarında üstalma ** operaötürünü kullanın. eslint: no-restricted-properties.

    // kötü
    const binary = Math.pow(2, 10);
    
    // iyi
    const binary = 2 ** 10;

⬆ başa dön

Değişkenler

  • 13.1 Değişken tanımlarında daima const ve let kullanın. Aksi halde global değişkenler oluşacaktır ve global namespace'i kirletmekten kaçınmalısınız. eslint: no-undef prefer-const

    // kötü
    superPower = new SuperPower();
    
    // iyi
    const superPower = new SuperPower();

  • 13.2 Her değişken ayrı ayrı const ya da let kullanın. eslint: one-var jscs: disallowMultipleVarDecl

    Neden? Bu şekilde yeni değişkenler tanımlamak kolaydır ve hata yapma olasılığınız daha azdır. Ayrıca bu şekilde değişkenler tek tek debug edilebilir.

    // kötü
    const items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';
    
    // kötü
    // (yukarıdaki ile kıyaslayarak yazım hatasını bulun)
    const items = getItems(),
        goSportsTeam = true;
        dragonball = 'z';
    
    // iyi
    const items = getItems();
    const goSportsTeam = true;
    const dragonball = 'z';

  • 13.3 Önce const sonra let değişkenlerini gruplayın.

    Neden? Bu şekilde daha önce tanımlanmış bir değişkeni farklı bir değişkene atamak daha kolaydır.

    // kötü
    let i, len, dragonball,
        items = getItems(),
        goSportsTeam = true;
    
    // kötü
    let i;
    const items = getItems();
    let dragonball;
    const goSportsTeam = true;
    let len;
    
    // iyi
    const goSportsTeam = true;
    const items = getItems();
    let dragonball;
    let i;
    let length;

  • 13.4 Değişkenleri kullanmanız gereken yerlerde tanımlayın ancak kabul edilebilir bir alanda oluşturun.

    Neden? let ve const fonksiyon scope'da değil block scope'da çalışır.

    // kötü
    function checkName(hasName) {
      const name = getName();
    
      if (hasName === 'test') {
        return false;
      }
    
      if (name === 'test') {
        this.setName('');
        return false;
      }
    
      return name;
    }
    
    // iyi
    function checkName(hasName) {
      if (hasName === 'test') {
        return false;
      }
    
      const name = getName();
    
      if (name === 'test') {
        this.setName('');
        return false;
      }
    
      return name;
    }

  • 13.5 Değişken tanımlarında zincir tekniğini kullanmayın. eslint: no-multi-assign

    Neden? Zincirleyerek oluşturmak, global değişkenler üretir.

    // kötü
    (function example() {
      // JavaScript işlemi aşağıdaki gibi ele alır.
      // let a = ( b = ( c = 1 ) );
      // let, sadece a'da uygulanır; b ve c
      // global değişkenler olacaktır.
      let a = b = c = 1;
    }());
    
    console.log(a); // ReferenceError
    console.log(b); // 1
    console.log(c); // 1
    
    // iyi
    (function example() {
      let a = 1;
      let b = a;
      let c = a;
    }());
    
    console.log(a); // ReferenceError
    console.log(b); // ReferenceError
    console.log(c); // ReferenceError
    
    // aynı şey `const` için de geçerlidir

  • 13.6 Eksiltme ve artırma operatörlerini kullanmaktan kaçının. (++, --). eslint no-plusplus

    Neden? Eslint dökümanına göre bu kullanım şeklinde otomatik noktalı virgüller eklenmekte ve gizli hataların oluşmasına neden olabilmektedir. Ayrıca num++ ya da num ++ yerine num += 1 şeklinde bir kullanım daha anlamlıdır. Ayrıca bu kullanım öncül artırma ve azaltmaya neden olabilecek hatalarında önüne geçer.

    // kötü
    
    const array = [1, 2, 3];
    let num = 1;
    num++;
    --num;
    
    let sum = 0;
    let truthyCount = 0;
    for (let i = 0; i < array.length; i++) {
      let value = array[i];
      sum += value;
      if (value) {
        truthyCount++;
      }
    }
    
    // iyi
    
    const array = [1, 2, 3];
    let num = 1;
    num += 1;
    num -= 1;
    
    const sum = array.reduce((a, b) => a + b, 0);
    const truthyCount = array.filter(Boolean).length;

  • 13.7 Tanımlama işlemlerinde ='den sonra satır atlamayın. Eğer tanım max-len hatasına neden oluyorsa değeri paranteze alın. eslint operator-linebreak.

    Neden? Satır atlamak ='de hataya neden olabilir.

    // kötü
    const foo =
      superLongLongLongLongLongLongLongLongFunctionName();
    
    // kötü
    const foo
      = 'superLongLongLongLongLongLongLongLongString';
    
    // iyi
    const foo = (
      superLongLongLongLongLongLongLongLongFunctionName()
    );
    
    // iyi
    const foo = 'superLongLongLongLongLongLongLongLongString';

⬆ başa dön

Hoisting

  • 14.1 var tanımlamaları en yakın fonksiyon scope'unun üstüne taşınır ancak karşılık olarak atanan değeri taşınmaz. const ve let ise Temporal Dead Zones (TDZ) adlı yeni bir konsept ile çalışır. typeof kullanımı artık sağlıklı değildir .

    // bu bölüm çalışmayacaktır (notDefined adlı
    // bir global değişken olmadığı için)
    function example() {
      console.log(notDefined); // => ReferenceError
    }
    
    // referansı atanmış değişkenler 
    // hoisting'den ötürü çalışırlar. Not: atanan değer
    // hoisted edilmeyecektir.
    function example() {
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    }
    
    // interpreter değişkeni hoist edecek ve
    // tanımı scope'un tepesine çıkaracaktır.
    // yani yukarıdaki örnek aşağıdaki şekilde 
    // yeniden yazılabilir.
    function example() {
      let declaredButNotAssigned;
      console.log(declaredButNotAssigned); // => undefined
      declaredButNotAssigned = true;
    }
    
    // let ve const ile
    function example() {
      console.log(declaredButNotAssigned); // => throws a ReferenceError
      console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
      const declaredButNotAssigned = true;
    }

  • 14.2 Anonim fonksiyon ifadelerinde isim yukarı taşınsada içerik taşınmaz.

    function example() {
      console.log(anonymous); // => undefined
    
      anonymous(); // => TypeError anonymous is not a function
    
      var anonymous = function () {
        console.log('anonymous function expression');
      };
    }

  • 14.3 Atanmış fonksiyon ifadelerinde değişken adı yukarı taşınsada, içerik ya da fonksiyon adı taşınmaz.

    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      superPower(); // => ReferenceError superPower is not defined
    
      var named = function superPower() {
        console.log('Flying');
      };
    }
    
    // fonksiyon ile değişken adı aynı olduğunda da
    // aynı durum geçerlidir.
    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      var named = function named() {
        console.log('named');
      };
    }

  • 14.4 Fonksiyon bildirimlerinde (tanımlarında) içerik ve isim yukarı taşınır.

    function example() {
      superPower(); // => Flying
    
      function superPower() {
        console.log('Flying');
      }
    }
  • Daha fazla bilgi için Ben Cherry'nin kaleme aldığı JavaScript Scoping & Hoisting yazısı okunabilir.

⬆ başa dön

Karşılaştırma Operatörleri

  • 15.1 == ve != yerine === ve !== kullanın. eslint: eqeqeq

  • 15.2 if gibi koşullu ifadelerinde ToBoolean metodu aşağıdaki kurallar ile uygulanır:

    • Objects, true ile değerlendirilir.
    • Undefined, false ile değerlendirilir.
    • Null, false ile değerlendirilir.
    • Booleans, the value of the boolean ile değerlendirilir.
    • Numbers, +0, -0, or NaN için false, aksi halde true ile değerlendirilir.
    • Strings, boş '' ise false, aksi halde true ile değerlendirilir.
    if ([0] && []) {
      // true
      // dizi (boş dahi olsa) bir nesnedir, nesneler true ile değerlenir.
    }

  • 15.3 Boolean için kısayolları kullanabilirsiniz ancak string ve number türlerinde kullanmamalısınız.

    // kötü
    if (isValid === true) {
      // ...
    }
    
    // iyi
    if (isValid) {
      // ...
    }
    
    // kötü
    if (name) {
      // ...
    }
    
    // iyi
    if (name !== '') {
      // ...
    }
    
    // kötü
    if (collection.length) {
      // ...
    }
    
    // iyi
    if (collection.length > 0) {
      // ...
    }

  • 15.5 Lexical tanımlar barındıran (let, const, function, ve class gibi) case ve default bloklarında süslü parantez kullanın. eslint: no-case-declarations

    Neden? Lexical tanımlamalar tüm switch bloğunda görünür durumdadır ve herhangi bir case çalıştığında uygulanır. Bu durum birden fazla case bulunması halinde aynı tanımlamanın çalışmasına neden olur.

    // kötü
    switch (foo) {
      case 1:
        let x = 1;
        break;
      case 2:
        const y = 2;
        break;
      case 3:
        function f() {
          // ...
        }
        break;
      default:
        class C {}
    }
    
    // iyi
    switch (foo) {
      case 1: {
        let x = 1;
        break;
      }
      case 2: {
        const y = 2;
        break;
      }
      case 3: {
        function f() {
          // ...
        }
        break;
      }
      case 4:
        bar();
        break;
      default: {
        class C {}
      }
    }

  • 15.6 Ternary operatörler tek satırda yazılmalıdır ve nested kullanımdan kaçınılmalıdır. eslint: no-nested-ternary

    // kötü
    const foo = maybe1 > maybe2
      ? "bar"
      : value1 > value2 ? "baz" : null;
    
    // 2 ayrı ifadeye bölünür
    const maybeNull = value1 > value2 ? 'baz' : null;
    
    // iyi
    const foo = maybe1 > maybe2
      ? 'bar'
      : maybeNull;
    
    // çok iyi
    const foo = maybe1 > maybe2 ? 'bar' : maybeNull;

  • 15.7 Gereksiz ternary ifadelerden kaçınılmalıdır. eslint: no-unneeded-ternary

    // kötü
    const foo = a ? a : b;
    const bar = c ? true : false;
    const baz = c ? false : true;
    
    // iyi
    const foo = a || b;
    const bar = !!c;
    const baz = !c;

  • 15.8 Operatörlerin karışması durumunda parantez kullanın. Standart aritmatik operatörlerde (+, -, *, & /) öncelik bilindiği için kullanılmasına gerek yoktur. eslint: no-mixed-operators

    Neden? Bu kullanım okunabilirliği artırır ve ifadeyi daha anlaşılır kılar.

    // kötü
    const foo = a && b < 0 || c > 0 || d + 1 === 0;
    
    // kötü
    const bar = a ** b - 5 % d;
    
    // kötü
    // karıştırılabilir (a || b) && c
    if (a || b && c) {
      return d;
    }
    
    // iyi
    const foo = (a && b < 0) || c > 0 || (d + 1 === 0);
    
    // iyi
    const bar = (a ** b) - (5 % d);
    
    // iyi
    if (a || (b && c)) {
      return d;
    }
    
    // iyi
    const bar = a + b / c * d;

⬆ başa dön

Bloklar

  • 16.1 Çok satırlı blokların tamamında süslü parantez kullanın. eslint: nonblock-statement-body-position

    // kötü
    if (test)
      return false;
    
    // iyi
    if (test) return false;
    
    // iyi
    if (test) {
      return false;
    }
    
    // kötü
    function foo() { return false; }
    
    // iyi
    function bar() {
      return false;
    }

  • 16.2 if ve else içeren çok satırlı bloklarda, else'i if bloğunun kapandığı satırda başlatın. eslint: brace-style jscs: disallowNewlineBeforeBlockStatements

    // kötü
    if (test) {
      thing1();
      thing2();
    }
    else {
      thing3();
    }
    
    // iyi
    if (test) {
      thing1();
      thing2();
    } else {
      thing3();
    }

  • 16.3 Eğer if bloğu daima bir return içeriyorsa, else bloğunu kullanmayın. return barındıran if bloğunu takip eden, return barındıran else if blokları birden fazla if bloğuna dönüştürülebilir. eslint: no-else-return

    // kötü
    function foo() {
      if (x) {
        return x;
      } else {
        return y;
      }
    }
    
    // kötü
    function cats() {
      if (x) {
        return x;
      } else if (y) {
        return y;
      }
    }
    
    // kötü
    function dogs() {
      if (x) {
        return x;
      } else {
        if (y) {
          return y;
        }
      }
    }
    
    // iyi
    function foo() {
      if (x) {
        return x;
      }
    
      return y;
    }
    
    // iyi
    function cats() {
      if (x) {
        return x;
      }
    
      if (y) {
        return y;
      }
    }
    
    //iyi
    function dogs(x) {
      if (x) {
        if (z) {
          return y;
        }
      } else {
        return z;
      }
    }

⬆ başa dön

Koşul İfadeleri

  • 17.1 Koşul ifadelerinizin (if, while etc.) uzun olması ya da maksimum karakter sayısını aşması durumunda her ifade grubunu ayrı satıra yazın. Mantıksal operatörler satır başında yer almalıdır.

    Neden? Karmaşık yapıyı sadeleştirerek okunabilirliği artıracaktır. Ayrıca metod zincirlerine benzer bir kalıptır.

    // kötü
    if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {
      thing1();
    }
    
    // kötü
    if (foo === 123 &&
      bar === 'abc') {
      thing1();
    }
    
    // kötü
    if (foo === 123
      && bar === 'abc') {
      thing1();
    }
    
    // kötü
    if (
      foo === 123 &&
      bar === 'abc'
    ) {
      thing1();
    }
    
    // iyi
    if (
      foo === 123
      && bar === 'abc'
    ) {
      thing1();
    }
    
    // iyi
    if (
      (foo === 123 || bar === 'abc')
      && doesItLookGoodWhenItBecomesThatLong()
      && isThisReallyHappening()
    ) {
      thing1();
    }
    
    // iyi
    if (foo === 123 && bar === 'abc') {
      thing1();
    }

  • 17.2 Selection operatörülerini kontrol ifadeleri içerisinde kullanmayın.

    // kötü
    !isRunning && startRunning();
    
    // iyi
    if (!isRunning) {
      startRunning();
    }

⬆ başa dön

Yorumlar

  • 18.1 Çok satırlı yorumlarda /** ... */ kullanın.

    // kötü
    // make() aktarılan tag'a göre
    // yeni bir element return eder
    //
    // @param {String} tag
    // @return {Element} element
    function make(tag) {
    
      // ...
    
      return element;
    }
    
    // iyi
    /**
     * make() aktarılan tag'a göre
     * yeni bir element return eder
     */
    function make(tag) {
    
      // ...
    
      return element;
    }

  • 18.2 Tek satırlı yorumlarda // kullanın. Yorumu, yorum yapılan betiğin üst satırına gelecek şekilde yazın. Eğer yorum, bloğun en üstünde yer almıyorsa daima yorumdan önce boş bir satır bırakın.

    // kötü
    const active = true;  // aktif bölüm
    
    // iyi
    // is current tab
    const active = true;
    
    // kötü
    function getType() {
      console.log('fetching type...');
      // varsayılanı 'no type' ayarlanır
      const type = this.type || 'no type';
    
      return type;
    }
    
    // iyi
    function getType() {
      console.log('fetching type...');
    
      // varsayılanı 'no type' ayarlanır
      const type = this.type || 'no type';
    
      return type;
    }
    
    // iyi
    function getType() {
      // varsayılanı 'no type' ayarlanır
      const type = this.type || 'no type';
    
      return type;
    }

  • 18.3 Yorumlardan önce okunabilirliği artırmak için bir boşluk karakteri kullanın. eslint: spaced-comment

    // kötü
    //aktif bölüm
    const active = true;
    
    // iyi
    // aktif bölüm
    const active = true;
    
    // kötü
    /**
     *make() aktarılan tag'a göre
     *yeni bir element return eder
     */
    function make(tag) {
    
      // ...
    
      return element;
    }
    
    // iyi
    /**
     * make() aktarılan tag'a göre
     * yeni bir element return eder
     */
    function make(tag) {
    
      // ...
    
      return element;
    }

  • 18.4 FIXME veya TODO kullanarak, geliştiricilere sorun hakkında bilgi verebilir ya da geliştiricilerin ilgili bölümde yapması gerekenler konusunda notlar bırakabilirsiniz. Bu kullanım standart yorumların aksine bir görevi işaret eder. Görevler; FIXME: -- bu sorunun çözülmesi gerekiyor veya TODO: -- bu işlevin implemente edilmesi gerekiyor.

  • 18.5 Sorunlara dikkat çekmek için // FIXME: kullanın.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // FIXME: burada global kullanılmamalı
        total = 0;
      }
    }

  • 18.6 Sorunlara çözüm önermek için // TODO: kullanın.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // TODO: total, options parametresi ile ayarlanabilmeli
        this.total = 0;
      }
    }

⬆ başa dön

Whitespace

  • 19.1 Soft tab'ı(boşluk karakteri) 2 boşluğa ayarlayın. eslint: indent jscs: validateIndentation

    // kötü
    function foo() {
    ∙∙∙∙let name;
    }
    
    // kötü
    function bar() {
    ∙let name;
    }
    
    // iyi
    function baz() {
    ∙∙let name;
    }

  • 19.2 Bloğu kapsayan süslü parantezini açmadan önce bir adet boşluk karakteri kullanın. eslint: space-before-blocks jscs: requireSpaceBeforeBlockStatements

    // kötü
    function test(){
      console.log('test');
    }
    
    // iyi
    function test() {
      console.log('test');
    }
    
    // kötü
    dog.set('attr',{
      age: '1 year',
      breed: 'Bernese Mountain Dog',
    });
    
    // iyi
    dog.set('attr', {
      age: '1 year',
      breed: 'Bernese Mountain Dog',
    });

  • 19.3 Koşul ifadelerindeki (if, while vb.) parantez öncesinde bir adet boşluk karakteri kullanın. Fonksiyon çağrıları ve fonksiyon bildirimlerindeki parametreler arasında ya da isimlerde boşluk kullanmayın. eslint: keyword-spacing jscs: requireSpaceAfterKeywords

    // kötü
    if(isJedi) {
      fight ();
    }
    
    // iyi
    if (isJedi) {
      fight();
    }
    
    // kötü
    function fight () {
      console.log ('Swooosh!');
    }
    
    // iyi
    function fight() {
      console.log('Swooosh!');
    }

  • 19.5 Dosya sonlarında yeni satır karakterini kullanın. eslint: eol-last

    // kötü
    import { es6 } from './AirbnbStyleGuide';
      // ...
    export default es6;
    // kötü
    import { es6 } from './AirbnbStyleGuide';
      // ...
    export default es6;
    
    // iyi
    import { es6 } from './AirbnbStyleGuide';
      // ...
    export default es6;

  • 19.6 Uzun metod zincirlerinde (2 den fazla) girintiler oluşturun. Nokta ile başlayan satırlar, satırın bir ifade değil bir metod çağrısı olduğunu belirtecektir. eslint: newline-per-chained-call no-whitespace-before-property

    // kötü
    $('#items').find('.selected').highlight().end().find('.open').updateCount();
    
    // kötü
    $('#items').
      find('.selected').
        highlight().
        end().
      find('.open').
        updateCount();
    
    // iyi
    $('#items')
      .find('.selected')
        .highlight()
        .end()
      .find('.open')
        .updateCount();
    
    // kötü
    const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true)
        .attr('width', (radius + margin) * 2).append('svg:g')
        .attr('transform', `translate(${radius + margin},${radius + margin})`)
        .call(tron.led);
    
    // iyi
    const leds = stage.selectAll('.led')
        .data(data)
      .enter().append('svg:svg')
        .classed('led', true)
        .attr('width', (radius + margin) * 2)
      .append('svg:g')
        .attr('transform', `translate(${radius + margin},${radius + margin})`)
        .call(tron.led);
    
    // iyi
    const leds = stage.selectAll('.led').data(data);

  • 19.7 Bloklardan sonra yeni ifadeye geçmeden önce bir adet boş satır bırakın. jscs: requirePaddingNewLinesAfterBlocks

    // kötü
    if (foo) {
      return bar;
    }
    return baz;
    
    // iyi
    if (foo) {
      return bar;
    }
    
    return baz;
    
    // kötü
    const obj = {
      foo() {
      },
      bar() {
      },
    };
    return obj;
    
    // iyi
    const obj = {
      foo() {
      },
    
      bar() {
      },
    };
    
    return obj;
    
    // kötü
    const arr = [
      function foo() {
      },
      function bar() {
      },
    ];
    return arr;
    
    // iyi
    const arr = [
      function foo() {
      },
    
      function bar() {
      },
    ];
    
    return arr;

  • 19.8 Blokların içinde boş satırlar bırakmayın. eslint: padded-blocks jscs: disallowPaddingNewlinesInBlocks

    // kötü
    function bar() {
    
      console.log(foo);
    
    }
    
    // kötü
    if (baz) {
    
      console.log(qux);
    } else {
      console.log(foo);
    
    }
    
    // kötü
    class Foo {
    
      constructor(bar) {
        this.bar = bar;
      }
    }
    
    // iyi
    function bar() {
      console.log(foo);
    }
    
    // iyi
    if (baz) {
      console.log(qux);
    } else {
      console.log(foo);
    }

  • 19.9 Parantez içinde boşluk kullanmayın. eslint: space-in-parens jscs: disallowSpacesInsideParentheses

    // kötü
    function bar( foo ) {
      return foo;
    }
    
    // iyi
    function bar(foo) {
      return foo;
    }
    
    // kötü
    if ( foo ) {
      console.log(foo);
    }
    
    // iyi
    if (foo) {
      console.log(foo);
    }

  • 19.12 100 karakterden uzun satırlar yazmayın. (whitespace dahil). Not: Uzun string'ler yukarıda belirtildiği gibi bu kuraldan muaftır. eslint: max-len jscs: maximumLineLength

    Neden? Geliştirilebilirliği ve okunabilirliği artırmaktadır.

    // kötü
    const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;
    
    // kötü
    $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));
    
    // iyi
    const foo = jsonData
      && jsonData.foo
      && jsonData.foo.bar
      && jsonData.foo.bar.baz
      && jsonData.foo.bar.baz.quux
      && jsonData.foo.bar.baz.quux.xyzzy;
    
    // iyi
    $.ajax({
      method: 'POST',
      url: 'https://airbnb.com/',
      data: { name: 'John' },
    })
      .done(() => console.log('Congratulations!'))
      .fail(() => console.log('You have failed this city.'));

⬆ başa dön

Virgüller

  • 20.1 Asla virgül ile başlamayın. eslint: comma-style jscs: requireCommaBeforeLineBreak

    // kötü
    const story = [
        once
      , upon
      , aTime
    ];
    
    // iyi
    const story = [
      once,
      upon,
      aTime,
    ];
    
    // kötü
    const hero = {
        firstName: 'Ada'
      , lastName: 'Lovelace'
      , birthYear: 1815
      , superPower: 'computers'
    };
    
    // iyi
    const hero = {
      firstName: 'Ada',
      lastName: 'Lovelace',
      birthYear: 1815,
      superPower: 'computers',
    };

  • 20.2 Liste sonlarında da kullanın. eslint: comma-dangle jscs: requireTrailingComma

    Neden? Git diff'lerini daha doğru şekilde gösterir. Ayrıca Babel gibi transpiler'lar fazladan virgülleri sileceği için tarayıcılardaki ilave virgül sorunu'nu düşünmenize gerek kalmayacaktır.

    // kötü - sonda virgül olmadığında git diff
    const hero = {
         firstName: 'Florence',
    -    lastName: 'Nightingale'
    +    lastName: 'Nightingale',
    +    inventorOf: ['coxcomb chart', 'modern nursing']
    };
    
    // iyi - sonda virgül olduğunda git diff
    const hero = {
         firstName: 'Florence',
         lastName: 'Nightingale',
    +    inventorOf: ['coxcomb chart', 'modern nursing'],
    };
    // kötü
    const hero = {
      firstName: 'Dana',
      lastName: 'Scully'
    };
    
    const heroes = [
      'Batman',
      'Superman'
    ];
    
    // iyi
    const hero = {
      firstName: 'Dana',
      lastName: 'Scully',
    };
    
    const heroes = [
      'Batman',
      'Superman',
    ];
    
    // kötü
    function createHero(
      firstName,
      lastName,
      inventorOf
    ) {
      // does nothing
    }
    
    // iyi
    function createHero(
      firstName,
      lastName,
      inventorOf,
    ) {
      // does nothing
    }
    
    // iyi (unutmayın rest elemanından sonra virgül kullanılmamalıdır)
    function createHero(
      firstName,
      lastName,
      inventorOf,
      ...heroArgs
    ) {
      // does nothing
    }
    
    // kötü
    createHero(
      firstName,
      lastName,
      inventorOf
    );
    
    // good
    createHero(
      firstName,
      lastName,
      inventorOf,
    );
    
    // iyi (unutmayın rest elemanından sonra virgül kullanılmamalıdır)
    createHero(
      firstName,
      lastName,
      inventorOf,
      ...heroArgs
    );

⬆ başa dön

Noktalı Virgüller

  • 21.1 Noktalı virgül kullanımına dikkat edilmelidir. eslint: semi jscs: requireSemicolons

    Neden? Javascript yorumlayıcıları noktalı virgül olmadan yeni satıra geçilen bölümleri Otomatik Noktalı Virgül Ekleme kuralları ile kontrol eder. Yanlış yorumlamalara karşı daima noktalı virgül kullanmanız gerekir. Ayrıca linter'ınızı yapılandırarak hatalı satır sonlarının otomatik olarak düzeltilmesini sağlayabilirsiniz.

    // kötü - hata verir
    const luke = {}
    const leia = {}
    [luke, leia].forEach(jedi => jedi.father = 'vader')
    
    // kötü - hata verir
    const reaction = "No! That's impossible!"
    (async function meanwhileOnTheFalcon() {
      // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
      // ...
    }())
    
    // kötü - değeri döndürmek yerine `undefined` döndürür - ASI'den ötürü return tek başına satırda olduğunda gerçekleşir!
    function foo() {
      return
        'search your feelings, you know it to be foo'
    }
    
    // iyi
    const luke = {};
    const leia = {};
    [luke, leia].forEach((jedi) => {
      jedi.father = 'vader';
    });
    
    // iyi
    const reaction = "No! That's impossible!";
    (async function meanwhileOnTheFalcon() {
      // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
      // ...
    }());
    
    // iyi
    function foo() {
      return 'search your feelings, you know it to be foo';
    }

    Daha fazla.

⬆ başa dön

Tip Dönüştürme

  • 22.1 Dönüştürme işlemlerini ifadelerin en başında uygulayın.

  • 22.2 String için; eslint: no-new-wrappers

    // => this.reviewScore = 9;
    
    // kötü
    const totalScore = new String(this.reviewScore); // totalScore'un typeof değeri "object"'dir. "string" değil.
    
    // kötü
    const totalScore = this.reviewScore + ''; // this.reviewScore.valueOf()'u uygular
    
    // kötü
    const totalScore = this.reviewScore.toString(); // string döneceğini garanti etmez
    
    // iyi
    const totalScore = String(this.reviewScore);

  • 22.3 Number için; Tip dönüştürme (Type Casting) işlemlerinde Number'ı kullanın ve stringleri, sayılara parse ederken tabanlara parseInt kullanarak ulaşın. eslint: radix no-new-wrappers

    const inputValue = '4';
    
    // kötü
    const val = new Number(inputValue);
    
    // kötü
    const val = +inputValue;
    
    // kötü
    const val = inputValue >> 0;
    
    // kötü
    const val = parseInt(inputValue);
    
    // iyi
    const val = Number(inputValue);
    
    // iyi
    const val = parseInt(inputValue, 10);

  • 22.4 Herhangi bir sebeple parseInt yerine performas sebebiyle Bitshift yapıyorsanız, nedenine ilişkin bir yorum bırakın.

    // iyi
    /**
     * parseInt yüzünden kodum yavaş çalışıyordu
     * Bitshifting String'i Number'a 
     * daha hızlı çeviriyor
     */
    const val = inputValue >> 0;

  • 22.5 Not: Bitshift işlemlerinde dikkatli olun. Number'lar 64-bit değeriyle sunulur fakat bitshift işlemleri daima 32-bit integer (source) döner. Bitshift işlemleri 32 bit'den büyük integer değerlerde beklenmeyen davranışlara neden olabilir. Tartışma. En büyük 32-bit Int 2,147,483,647:

    2147483647 >> 0; // => 2147483647
    2147483648 >> 0; // => -2147483648
    2147483649 >> 0; // => -2147483647

  • 22.6 Boolean için; eslint: no-new-wrappers

    const age = 0;
    
    // kötü
    const hasAge = new Boolean(age);
    
    // iyi
    const hasAge = Boolean(age);
    
    // çok iyi
    const hasAge = !!age;

⬆ başa dön

İsimlendirme

  • 23.1 Tek harfli isimlendirmelerden kaçının. İsimlerde açıklayıcı olun. eslint: id-length

    // kötü
    function q() {
      // ...
    }
    
    // iyi
    function query() {
      // ...
    }

  • 23.2 Nesne, fonksiyon, ve instance'larda camelCase isimlendirme yapın. eslint: camelcase jscs: requireCamelCaseOrUpperCaseIdentifiers

    // kötü
    const OBJEcttsssss = {};
    const this_is_my_object = {};
    function c() {}
    
    // iyi
    const thisIsMyObject = {};
    function thisIsMyFunction() {}

  • 23.3 Sınıf ve constructor'larda pascalCase kullanın. eslint: new-cap jscs: requireCapitalizedConstructors

    // kötü
    function user(options) {
      this.name = options.name;
    }
    
    const bad = new user({
      name: 'nope',
    });
    
    // iyi
    class User {
      constructor(options) {
        this.name = options.name;
      }
    }
    
    const good = new User({
      name: 'yup',
    });

  • 23.4 Sonlarda ve başlarda alt çizgi kullanmayın. eslint: no-underscore-dangle jscs: disallowDanglingUnderscores

    Neden? JavaScript property ve metodlarında private konsepti yoktur. Alt çizgi kullanımı genel olarak “private”'e karşılık kullanılır fakat propertyler tümüyle public'dir. Bu şekilde bir kullanım geliştiricileri yanıltabilir.

    // kötü
    this.__firstName__ = 'Panda';
    this.firstName_ = 'Panda';
    this._firstName = 'Panda';
    
    // iyi
    this.firstName = 'Panda';
    
    // iyi
    // see https://kangax.github.io/compat-table/es6/#test-WeakMap
    const firstNames = new WeakMap();
    firstNames.set(this, 'Panda');

  • 23.5 Referansları this ile aktarmayın. Arrow fonksiyonları ya da Function#bind kullanın. jscs: disallowNodeTypes

    // kötü
    function foo() {
      const self = this;
      return function () {
        console.log(self);
      };
    }
    
    // kötü
    function foo() {
      const that = this;
      return function () {
        console.log(that);
      };
    }
    
    // iyi
    function foo() {
      return () => {
        console.log(this);
      };
    }

  • 23.6 Ana dosya adı default export adı ile birebir uyuşmalıdır.

    // file 1 contents
    class CheckBox {
      // ...
    }
    export default CheckBox;
    
    // file 2 contents
    export default function fortyTwo() { return 42; }
    
    // file 3 contents
    export default function insideDirectory() {}
    
    // in some other file
    // kötü
    import CheckBox from './checkBox'; // PascalCase import/export, camelCase dosya adı
    import FortyTwo from './FortyTwo'; // PascalCase import/dosya adı, camelCase export
    import InsideDirectory from './InsideDirectory'; // PascalCase import/dosya adı, camelCase export
    
    // kötü
    import CheckBox from './check_box'; // PascalCase import/export, snake_case dosya adı
    import forty_two from './forty_two'; // snake_case import/dosya adı, camelCase export
    import inside_directory from './inside_directory'; // snake_case import, camelCase export
    import index from './inside_directory/index'; // index dosyasını zorunlu kılar
    import insideDirectory from './insideDirectory/index'; // index dosyasını zorunlu kılar
    
    // iyi
    import CheckBox from './CheckBox'; // PascalCase export/import/dosya adı
    import fortyTwo from './fortyTwo'; // camelCase export/import/dosya adı
    import insideDirectory from './insideDirectory'; // camelCase export/import/klasör name/implicit "index"
    // ^ hem insideDirectory.js hem de insideDirectory/index.js için geçerlidir

  • 23.7 Default export fonksiyonlarında camelCase kullanın. Dosya adınız fonksiyon adı ile aynı olmalıdır.

    function makeStyleGuide() {
      // ...
    }
    
    export default makeStyleGuide;

  • 23.8 Constructor / class / singleton / function library / bare object; export ederken PascalCase kullanın.

    const AirbnbStyleGuide = {
      es6: {
      },
    };
    
    export default AirbnbStyleGuide;

  • 23.9 Kısaltma isimlerin tümü büyük harfle ya da küçük harfle yazılmalıdır.

    Neden? İsimler bilgisayar algoritması değildir ve okunabilirliğe göre seçilmelidir.

    // kötü
    import SmsContainer from './containers/SmsContainer';
    
    // kötü
    const HttpRequests = [
      // ...
    ];
    
    // iyi
    import SMSContainer from './containers/SMSContainer';
    
    // iyi
    const HTTPRequests = [
      // ...
    ];
    
    // iyi
    const httpRequests = [
      // ...
    ];
    
    // çok iyi
    import TextMessageContainer from './containers/TextMessageContainer';
    
    // çok iyi
    const requests = [
      // ...
    ];

⬆ başa dön

Accessor

  • 24.1 Propertylerde accessor fonksiyon kullanımı gerekli değildir.

  • 24.2 Get/set fonksiyonlarını javascript'de kullanmayın. Beklenmeyen yan etkiler oluşturabilir ve test edilmesi, geliştirilmesi zordur. Bunun yerine gerekirse getVal() ve setVal('hello') şeklinde kullanın.

    // kötü
    class Dragon {
      get age() {
        // ...
      }
    
      set age(value) {
        // ...
      }
    }
    
    // iyi
    class Dragon {
      getAge() {
        // ...
      }
    
      setAge(value) {
        // ...
      }
    }

  • 24.3 Eğer property/metod boolean ise, isVal() veya hasVal() kullanın.

    // kötü
    if (!dragon.age()) {
      return false;
    }
    
    // iyi
    if (!dragon.hasAge()) {
      return false;
    }

  • 24.4 get() ve set() fonksiyonları oluşturabilirsiniz fakat daima tutarlı olun.

    class Jedi {
      constructor(options = {}) {
        const lightsaber = options.lightsaber || 'blue';
        this.set('lightsaber', lightsaber);
      }
    
      set(key, val) {
        this[key] = val;
      }
    
      get(key) {
        return this[key];
      }
    }

⬆ başa dön

Olaylar

  • 25.1 Verileri olaylara (event) bağlarken (DOM event'i ya da Backbone event'i gibi daha özel bir event farketmez), ham bir değer yerine sabit bir nesne kullanın. ("hash" olarak bilinir) Bu sayede sonraki akışlarda olay için tüm olay tutucuların (event handler) çalışmasının önüne geçilir.

    // kötü
    $(this).trigger('listingUpdated', listing.id);
    
    // ...
    
    $(this).on('listingUpdated', (e, listingID) => {
      // do something with listingID
    });
    // iyi
    $(this).trigger('listingUpdated', { listingID: listing.id });
    
    // ...
    
    $(this).on('listingUpdated', (e, data) => {
      // do something with data.listingID
    });

⬆ başa dön

jQuery

  • 26.1 jQuery değişkenlerinde $ öneki kullanın. jscs: requireDollarBeforejQueryAssignment

    // kötü
    const sidebar = $('.sidebar');
    
    // iyi
    const $sidebar = $('.sidebar');
    
    // iyi
    const $sidebarBtn = $('.sidebar-btn');

  • 26.2 jQuery lookup'larını önbelleğe alın.

    // kötü
    function setSidebar() {
      $('.sidebar').hide();
    
      // ...
    
      $('.sidebar').css({
        'background-color': 'pink',
      });
    }
    
    // iyi
    function setSidebar() {
      const $sidebar = $('.sidebar');
      $sidebar.hide();
    
      // ...
    
      $sidebar.css({
        'background-color': 'pink',
      });
    }

  • 26.3 DOM query'lerde cascading $('.sidebar ul') ya da parent > child $('.sidebar > ul') yöntemini kullanın. jsPerf

  • 26.4 Scope içerisinde çalışan jQuery sorgularında find kullanın.

    // kötü
    $('ul', '.sidebar').hide();
    
    // kötü
    $('.sidebar').find('ul').hide();
    
    // iyi
    $('.sidebar ul').hide();
    
    // iyi
    $('.sidebar > ul').hide();
    
    // iyi
    $sidebar.find('ul').hide();

⬆ başa dön

ECMAScript 5 Uyumluluğu

⬆ başa dön

ECMAScript 6+ (ES 2015+) Özellikleri

  • 28.1 Aşağıda çeşitli ES6+ özelliklerinin bir listesini bulabilirsiniz.
  1. Arrow Fonksiyonlar
  2. Sınıflar
  3. Nesnelerde Shorthand
  4. Nesnelerde Concise
  5. Dinamik Şekilde Oluşturulan Nesne Property'leri
  6. String Şablonları
  7. Destructuring
  8. Varsayılan Parametreler
  9. Rest
  10. Dizilerde Spread
  11. Let ve Const
  12. Üsalma operatörü
  13. Yineleyiciler ve Oluşturucular
  14. Modüller

⬆ başa dön

Yerleşik Kütüphaneler

Yerleşik Kütüphaneler fonksiyonel açıdan hatalı olsada legacy sebebiyle varlığını koruyan araçlar içerir.

  • 29.1 Global isNaN yerine Number.isNaN kullanın. eslint: no-restricted-globals

    Neden? Global isNaN sayı-olmayan değerlerde de true döndürebilir. Eğer bu davranışı görmezden gelecekseniz bunu belli edin.

    // kötü
    isNaN('1.2'); // false
    isNaN('1.2.3'); // true
    
    // iyi
    Number.isNaN('1.2.3'); // false
    Number.isNaN(Number('1.2.3')); // true

  • 29.2 Global isFinite yerine Number.isFinite kullanın. eslint: no-restricted-globals

    Neden? Global isFinite sayı-olmayan değerlerde de true döndürebilir. Eğer bu davranışı görmezden gelecekseniz bunu belli edin.

    // kötü
    isFinite('2e3'); // true
    
    // iyi
    Number.isFinite('2e3'); // false
    Number.isFinite(parseInt('2e3', 10)); // true

⬆ başa dön

Test

  • 30.1 Daima test yazılmalıdır.

    function foo() {
      return true;
    }

  • 30.2 Dikkat edeceğiniz bazı kurallar:
    • Hangi test framework'ünü kullanırsanız kullanın mutlaka test yazın!
    • Sade ve kısa fonksiyonlar ile mutasyonları minimize edin.
    • Stub ve mock'lara karşı dikkatli olun - testlerinizi kırılgan hale getirebilirler.
    • Airbnb'de genel de mocha kullanıyoruz. Zaman zaman küçük ve harici modüllerde tape de kullanıyoruz.
    • Pratikte ulaşması güç olsada test kapsamında (test coverage) %100, iyi bir hedeftir.
    • Her bug düzeltildiğinde bir regresyon testi yazın Regresyon testi yapılmadan düzeltilen bir hatanın yeniden oluşması olasıdır.

⬆ başa dön

Performans

⬆ başa dön

Kaynaklar

ES6+ Öğrenin

Okuyun

Araçlar

Diğer Stil Kılavuzları

Diğer Stiller

İlave Okumalar

Kitaplar

Bloglar

Podcastler

⬆ başa dön

Organizasyonlar

Kılavuzumuzu kullanan organizasyonların listesi. Pull request göndererek eklemelerde bulunabilirsiniz.

⬆ başa dön

Çeviri

Bu rehbere farklı dillerden de erişilebilir:

Kılavuz Kılavuzu

JavaScript Sohbet Kanalı

  • gitter'dan ulaşabilirsiniz.

Katkıda Bulunanlar

Lisans

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

⬆ başa dön

Değişiklikler

Bu kılavuzu fork'layıp takımınıza uygun hale getirmenizden memnuniyet duyarız. Buraya size özel değişiklikleri eklerseniz yapacağınız güncellemelerde merge conflict'leri daha rahat çözebilirsiniz.

};