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.
Bu rehbere farklı dillerden de erişilebilir. Çeviri
Diğer Rehberler
- Veri Türleri
- Referanslar
- Nesneler
- Diziler
- Destructuring
- String
- Fonksiyonlar
- Arrow Fonksiyonlar
- Sınıflar & Constructor
- Modüller
- Yineleyiciler ve Oluşturucular
- Property
- Değişkenler
- Hoisting
- Karşılaştırma Operatörleri
- Bloklar
- Koşul İfadeleri
- Yorumlar
- Whitespace
- Virgüller
- Noktalı Virgüller
- Tip Dönüştürme
- İsimlendirme
- Accessor
- Olaylar
- jQuery
- ECMAScript 5 Uyumluluğu
- ECMAScript 6+ (ES 2015+) Özellikleri
- Yerleşik Kütüphaneler
- Test
- Performans
- Kaynaklar
- Organizasyonlar
- Çeviri
- Kılavuz Kılavuzu
- JavaScript Sohbet Kanalı
- Katkıda Bulunanlar
- Lisans
- Değişiklikler
-
1.1 Birincil: Birincil(İlkel) bir türe eriştiğinizde doğrudan değer ile karşılaşırsınız.
stringnumberbooleannullundefinedsymbol
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.
objectarrayfunction
const foo = [1, 2]; const bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9
-
2.1 Tüm referanslarda
constkullanın.varkullanmaktan kaçının. eslint:prefer-const,no-const-assignNeden? 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,
varyerineletkullanın. eslint:no-varjscs:disallowVarNeden?
letblock-scopevarfunction-scope'dur.// kötü var count = 1; if (true) { count += 1; } // iyi let count = 1; if (true) { count += 1; }
-
2.3 Unutmayın;
letveconst'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ı)
-
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-shorthandjscs: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-shorthandjscs:requireEnhancedObjectLiteralsNeden? 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-propsjscs:disallowQuotedKeysInObjectsNeden? 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,propertyIsEnumerableveisPrototypeOfgibiObject.prototypemetodları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.assignyerine 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 }
-
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, ];
-
5.1 Bir nesneden birden fazla property'e erişirken destructuring tekniğini kullanın. eslint:
prefer-destructuringjscs:requireObjectDestructuringNeden ? 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.2 Dizilerde de destructuring tekniğini kullanın. eslint:
prefer-destructuringjscs:requireArrayDestructuringconst arr = [1, 2, 3, 4]; // kötü const first = arr[0]; const second = arr[1]; // iyi const [first, second] = arr;
-
5.3 Birden fazla değer dönmesi durumunda diziler yerine nesneler ile destructuring yapın. jscs:
disallowArrayDestructuringReturnNeden? 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);
-
6.1 String'lerde tek tırnak
''kullanın. eslint:quotesjscs: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-templatetemplate-curly-spacingjscs:requireTemplateStringsNeden? 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-escapeNeden? 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}'`;
-
7.1 Klasik fonksiyon tanımları yerine isimlendirilmiş fonksiyon ifadeleri kullanın. eslint:
func-stylejscs:disallowFunctionDeclarationsNeden? 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-iifejscs:requireParenthesesAroundIIFENeden? 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
blockkavramı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
argumentsadını vermeyin. Bu şekilde bir kullanım her fonksiyonun blok alanında bulunanargumentsnesnesinin üzerinde kalacaktır.// kötü function foo(name, options, arguments) { // ... } // iyi function foo(name, options, args) { // ... }
-
7.6
argumentsyerine içeriğe rest...ile ulaşın. eslint:prefer-rest-paramsNeden?
...ile sadece istenen argümanlara erişebilirsiniz. Ayrıca rest argümanlar dizi-benzeriarguments'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-funcNeden? 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-parenspace-before-blocksNeden? 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-reassignNeden? 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-reassignNeden? Parametrelerin yeniden tanımlanması özellikle
argumentsnesnesine 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-spreadNeden? Daha temiz bir kullanım şeklidir. İçeriği oluşturmanıza ve
newileapplykullanmanı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, );
-
8.1 İsimsiz bir fonksiyon kullanırken (fonksiyon içi bir callback olarak) arrow (ok) fonksiyon notasyonunu kullanın. eslint:
prefer-arrow-callback,arrow-spacingjscs:requireArrowFunctionsNeden? Bu kullanım ihtiyaç duyulduğu gibi,
thisile ç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
returnkullanın. eslint:arrow-parens,arrow-body-stylejscs:disallowParenthesesAroundArrowParam,requireShorthandArrowFunctionsNeden? 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-parensjscs:disallowParenthesesAroundArrowParamNeden? 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; };
-
9.1 Daima
classkullanın. Doğrudanprototypemanipulasyonundan kaçının.Neden?
classsö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
thisreturn 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-membersNeden? 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; } }
-
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-importsNeden? 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-exportsNeden? 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-exportNeden? 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/firstNeden?
importkullanı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-syntaxNeden? Webpack sözdizimi module bundler'da importları çoğaltır. Bunun yerine loader sözdizimini
webpack.config.jsiç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';
-
11.1 Yineleyici (Iterator) kullanmayın.
for-invefor-ofgibi döngülerde higher-order fonksiyonları tercih edin. eslint:no-iteratorno-restricted-syntaxNeden? 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-spacingNeden?
functionve*kavramsal terimlerdir.*,functioniç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* () { // ... };
-
12.1 Property'lere erişirken nokta notasyonunu kullanın. eslint:
dot-notationjscs:requireDotNotationconst 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;
-
13.1 Değişken tanımlarında daima
constveletkullanın. Aksi halde global değişkenler oluşacaktır ve global namespace'i kirletmekten kaçınmalısınız. eslint:no-undefprefer-const// kötü superPower = new SuperPower(); // iyi const superPower = new SuperPower();
-
13.2 Her değişken ayrı ayrı
constya daletkullanın. eslint:one-varjscs:disallowMultipleVarDeclNeden? 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
constsonraletdeğ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?
letveconstfonksiyon 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-assignNeden? 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-plusplusNeden? 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 danum ++yerinenum += 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ımmax-lenhatasına neden oluyorsa değeri paranteze alın. eslintoperator-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';
-
14.1
vartanımlamaları en yakın fonksiyon scope'unun üstüne taşınır ancak karşılık olarak atanan değeri taşınmaz.constveletise 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.
-
15.2
ifgibi koşullu ifadelerindeToBooleanmetodu 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.4 Daha fazla bilgi için Angus Croll tarafından kaleme alınan Truth Equality and JavaScript adlı yazısını inceleyin.
-
15.5 Lexical tanımlar barındıran (
let,const,function, veclassgibi)casevedefaultbloklarında süslü parantez kullanın. eslint:no-case-declarationsNeden? Lexical tanımlamalar tüm
switchbloğunda görünür durumdadır ve herhangi bircaseçalıştığında uygulanır. Bu durum birden fazlacasebulunması 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-operatorsNeden? 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;
-
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
ifveelseiçeren çok satırlı bloklarda,else'iifbloğunun kapandığı satırda başlatın. eslint:brace-stylejscs:disallowNewlineBeforeBlockStatements// kötü if (test) { thing1(); thing2(); } else { thing3(); } // iyi if (test) { thing1(); thing2(); } else { thing3(); }
-
16.3 Eğer
ifbloğu daima birreturniçeriyorsa,elsebloğunu kullanmayın.returnbarındıranifbloğunu takip eden,returnbarındıranelse ifblokları birden fazlaifbloğ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; } }
-
17.1 Koşul ifadelerinizin (
if,whileetc.) 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(); }
-
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
FIXMEveyaTODOkullanarak, 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 gerekiyorveyaTODO: -- 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; } }
-
19.1 Soft tab'ı(boşluk karakteri) 2 boşluğa ayarlayın. eslint:
indentjscs: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-blocksjscs: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,whilevb.) 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-spacingjscs:requireSpaceAfterKeywords// kötü if(isJedi) { fight (); } // iyi if (isJedi) { fight(); } // kötü function fight () { console.log ('Swooosh!'); } // iyi function fight() { console.log('Swooosh!'); }
-
19.4 Operatörleri boşluk karakteri ile ayırın. eslint:
space-infix-opsjscs:requireSpaceBeforeBinaryOperators,requireSpaceAfterBinaryOperators// kötü const x=y+5; // iyi const x = y + 5;
-
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-callno-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-blocksjscs: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-parensjscs: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.10 Köşeli parantez içinde boşluk kullanmayın. eslint:
array-bracket-spacingjscs:disallowSpacesInsideArrayBrackets// kötü const foo = [ 1, 2, 3 ]; console.log(foo[ 0 ]); // iyi const foo = [1, 2, 3]; console.log(foo[0]);
-
19.11 Süslü parantez içinde boşluk kullanın. eslint:
object-curly-spacingjscs:requireSpacesInsideObjectBrackets// kötü const foo = {clark: 'kent'}; // iyi const foo = { clark: 'kent' };
-
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-lenjscs:maximumLineLengthNeden? 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.'));
-
20.1 Asla virgül ile başlamayın. eslint:
comma-stylejscs: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-danglejscs:requireTrailingCommaNeden? 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 );
-
21.1 Noktalı virgül kullanımına dikkat edilmelidir. eslint:
semijscs:requireSemicolonsNeden? 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'; }
- 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 tabanlaraparseIntkullanarak ulaşın. eslint:radixno-new-wrappersconst 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
parseIntyerine 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-wrappersconst age = 0; // kötü const hasAge = new Boolean(age); // iyi const hasAge = Boolean(age); // çok iyi const hasAge = !!age;
-
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:
camelcasejscs: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-capjscs: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-danglejscs:disallowDanglingUnderscoresNeden? 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ı
thisile 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 = [ // ... ];
- 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
booleanise,isVal()veyahasVal()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]; } }
-
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 });
-
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
findkullanı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();
- 27.1 Kangax'ın ES5 uyumluluk tablosu'nu inceleyin.
- 28.1 Aşağıda çeşitli ES6+ özelliklerinin bir listesini bulabilirsiniz.
- Arrow Fonksiyonlar
- Sınıflar
- Nesnelerde Shorthand
- Nesnelerde Concise
- Dinamik Şekilde Oluşturulan Nesne Property'leri
- String Şablonları
- Destructuring
- Varsayılan Parametreler
- Rest
- Dizilerde Spread
- Let ve Const
- Üsalma operatörü
- Yineleyiciler ve Oluşturucular
- Modüller
-
28.2 3. aşamaya ulaşmamış TC39 önerileri'ni kullanmayın.
Neden? Henüz tamamlanmadı ve halen baştan aşağı değiştirilebilir.
Yerleşik Kütüphaneler fonksiyonel açıdan hatalı olsada legacy sebebiyle varlığını koruyan araçlar içerir.
-
29.1 Global
isNaNyerineNumber.isNaNkullanın. eslint:no-restricted-globalsNeden? Global
isNaNsayı-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
isFiniteyerineNumber.isFinitekullanın. eslint:no-restricted-globalsNeden? Global
isFinitesayı-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
-
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
mochakullanıyoruz. Zaman zaman küçük ve harici modüllerdetapede 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.
- On Layout & Web Performance
- String vs Array Concat
- Try/Catch Cost In a Loop
- Bang Function
- jQuery Find vs Context, Selector
- innerHTML vs textContent for script text
- Long String Concatenation
- Are Javascript functions like
map(),reduce(), andfilter()optimized for traversing arrays? - Loading...
ES6+ Öğrenin
Okuyun
Araçlar
- Code Style Linters
- ESlint - Airbnb Style .eslintrc
- JSHint - Airbnb Style .jshintrc
- JSCS - Airbnb Style Preset (Deprecated, please use ESlint)
- Neutrino preset - neutrino-preset-airbnb-base
Diğer Stil Kılavuzları
- Google JavaScript Style Guide
- jQuery Core Style Guidelines
- Principles of Writing Consistent, Idiomatic JavaScript
Diğer Stiller
- Naming this in nested functions - Christian Johansen
- Conditional Callbacks - Ross Allen
- Popular JavaScript Coding Conventions on GitHub - JeongHoon Byun
- Multiple var statements in JavaScript, not superfluous - Ben Alman
İlave Okumalar
- Understanding JavaScript Closures - Angus Croll
- Basic JavaScript for the impatient programmer - Dr. Axel Rauschmayer
- You Might Not Need jQuery - Zack Bloom & Adam Schwartz
- ES6 Features - Luke Hoban
- Frontend Guidelines - Benjamin De Cock
Kitaplar
- JavaScript: The Good Parts - Douglas Crockford
- JavaScript Patterns - Stoyan Stefanov
- Pro JavaScript Design Patterns - Ross Harmes and Dustin Diaz
- High Performance Web Sites: Essential Knowledge for Front-End Engineers - Steve Souders
- Maintainable JavaScript - Nicholas C. Zakas
- JavaScript Web Applications - Alex MacCaw
- Pro JavaScript Techniques - John Resig
- Smashing Node.js: JavaScript Everywhere - Guillermo Rauch
- Secrets of the JavaScript Ninja - John Resig and Bear Bibeault
- Human JavaScript - Henrik Joreteg
- Superhero.js - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
- JSBooks - Julien Bouquillon
- Third Party JavaScript - Ben Vinegar and Anton Kovalyov
- Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript - David Herman
- Eloquent JavaScript - Marijn Haverbeke
- You Don’t Know JS: ES6 & Beyond - Kyle Simpson
Bloglar
- JavaScript Weekly
- JavaScript, JavaScript...
- Bocoup Weblog
- Adequately Good
- NCZOnline
- Perfection Kills
- Ben Alman
- Dmitry Baranovskiy
- nettuts
Podcastler
Kılavuzumuzu kullanan organizasyonların listesi. Pull request göndererek eklemelerde bulunabilirsiniz.
- 123erfasst: 123erfasst/javascript
- 3blades: 3Blades
- 4Catalyzer: 4Catalyzer/javascript
- Aan Zee: AanZee/javascript
- Adult Swim: adult-swim/javascript
- Airbnb: airbnb/javascript
- AltSchool: AltSchool/javascript
- Apartmint: apartmint/javascript
- Ascribe: ascribe/javascript
- Avalara: avalara/javascript
- Avant: avantcredit/javascript
- Axept: axept/javascript
- BashPros: BashPros/javascript
- Billabong: billabong/javascript
- Bisk: bisk
- Bonhomme: bonhommeparis/javascript
- Brainshark: brainshark/javascript
- CaseNine: CaseNine/javascript
- Chartboost: ChartBoost/javascript-style-guide
- ComparaOnline: comparaonline/javascript
- Compass Learning: compasslearning/javascript-style-guide
- DailyMotion: dailymotion/javascript
- DoSomething: DoSomething/eslint-config
- Digitpaint digitpaint/javascript
- Ecosia: ecosia/javascript
- Evernote: evernote/javascript-style-guide
- Evolution Gaming: evolution-gaming/javascript
- EvozonJs: evozonjs/javascript
- ExactTarget: ExactTarget/javascript
- Expensify Expensify/Style-Guide
- Flexberry: Flexberry/javascript-style-guide
- Gawker Media: gawkermedia
- General Electric: GeneralElectric/javascript
- Generation Tux: GenerationTux/javascript
- GoodData: gooddata/gdc-js-style
- GreenChef: greenchef/javascript
- Grooveshark: grooveshark/javascript
- Grupo-Abraxas: Grupo-Abraxas/javascript
- Honey: honeyscience/javascript
- How About We: howaboutwe/javascript
- Huballin: huballin
- HubSpot: HubSpot/javascript
- Hyper: hyperoslo/javascript-playbook
- InterCity Group: intercitygroup/javascript-style-guide
- Jam3: Jam3/Javascript-Code-Conventions
- JeopardyBot: kesne/jeopardy-bot
- JSSolutions: JSSolutions/javascript
- Kaplan Komputing: kaplankomputing/javascript
- KickorStick: kickorstick
- Kinetica Solutions: kinetica/javascript
- LEINWAND: LEINWAND/javascript
- Lonely Planet: lonelyplanet/javascript
- M2GEN: M2GEN/javascript
- Mighty Spring: mightyspring/javascript
- MinnPost: MinnPost/javascript
- MitocGroup: MitocGroup/javascript
- ModCloth: modcloth/javascript
- Money Advice Service: moneyadviceservice/javascript
- Muber: muber
- National Geographic: natgeo
- Nimbl3: nimbl3/javascript
- Nulogy: nulogy/javascript
- Orange Hill Development: orangehill/javascript
- Orion Health: orionhealth/javascript
- OutBoxSoft: OutBoxSoft/javascript
- Peerby: Peerby/javascript
- Razorfish: razorfish/javascript-style-guide
- reddit: reddit/styleguide/javascript
- React: facebook.github.io/react/contributing/how-to-contribute.html#style-guide
- REI: reidev/js-style-guide
- Ripple: ripple/javascript-style-guide
- Sainsbury's Supermarkets: jsainsburyplc
- SeekingAlpha: seekingalpha/javascript-style-guide
- Shutterfly: shutterfly/javascript
- Sourcetoad: sourcetoad/javascript
- Springload: springload
- StratoDem Analytics: stratodem/javascript
- SteelKiwi Development: steelkiwi/javascript
- StudentSphere: studentsphere/javascript
- SwoopApp: swoopapp/javascript
- SysGarage: sysgarage/javascript-style-guide
- Syzygy Warsaw: syzygypl/javascript
- Target: target/javascript
- TheLadders: TheLadders/javascript
- The Nerdery: thenerdery/javascript-standards
- T4R Technology: T4R-Technology/javascript
- VoxFeed: VoxFeed/javascript-style-guide
- WeBox Studio: weboxstudio/javascript
- Weggo: Weggo/javascript
- Zillow: zillow/javascript
- ZocDoc: ZocDoc/javascript
Bu rehbere farklı dillerden de erişilebilir:
Brazilian Portuguese: armoucar/javascript-style-guide
Bulgarian: borislavvv/javascript
Catalan: fpmweb/javascript-style-guide
Chinese (Simplified): yuche/javascript
Chinese (Traditional): jigsawye/javascript
French: nmussy/javascript-style-guide
German: timofurrer/javascript-style-guide
Italian: sinkswim/javascript-style-guide
Japanese: mitsuruog/javascript-style-guide
Korean: ParkSB/javascript-style-guide
Russian: leonidlebedev/javascript-airbnb
Spanish: paolocarrasco/javascript-style-guide
Thai: lvarayut/javascript-style-guide
Turkish: eraycetinay/javascript
Ukrainian: ivanzusko/javascript
Vietnam: hngiang/javascript-style-guide
- gitter'dan ulaşabilirsiniz.
(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.
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.