└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # Airbnb JavaScript Style Guide() {
2 |
3 | *JavaScript'e daha akıllıca bir yaklaşım*
4 |
5 | > **Not**: Bu rehber [babel-preset-airbnb](https://npmjs.com/babel-preset-airbnb) ile birlikte [Babel](https://babeljs.io) ya da benzeri bir derleyici kullandığınızı varsayar. Ayrıca tarayıcı uyumluluğu için uygulamalarınızda [airbnb-browser-shims](https://npmjs.com/airbnb-browser-shims) veya benzer bir shims/polyfills kurmanız gerekecektir.
6 |
7 | [](https://www.npmjs.com/package/eslint-config-airbnb)
8 | [](https://www.npmjs.com/package/eslint-config-airbnb-base)
9 | [](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
10 |
11 | Bu rehbere farklı dillerden de erişilebilir. [Çeviri](#Çeviri)
12 |
13 | Diğer Rehberler
14 |
15 | - [ES5 (Kullanımdan Kaldırıldı)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5)
16 | - [React](https://github.com/airbnb/javascript/tree/master/react)
17 | - [CSS-in-JavaScript](https://github.com/airbnb/javascript/tree/master/css-in-javascript)
18 | - [CSS & Sass](https://github.com/airbnb/css)
19 | - [Ruby](https://github.com/airbnb/ruby)
20 |
21 | ## İçindekiler
22 |
23 | 1. [Veri Türleri](#veri-türleri)
24 | 1. [Referanslar](#referanslar)
25 | 1. [Nesneler](#nesneler)
26 | 1. [Diziler](#diziler)
27 | 1. [Destructuring](#destructuring)
28 | 1. [String](#string)
29 | 1. [Fonksiyonlar](#fonksiyonlar)
30 | 1. [Arrow Fonksiyonlar](#arrow-fonksiyonlar)
31 | 1. [Sınıflar & Constructor](#sınıflar--constructor)
32 | 1. [Modüller](#modüller)
33 | 1. [Yineleyiciler ve Oluşturucular](#yineleyiciler-ve-oluşturucular)
34 | 1. [Property](#properties)
35 | 1. [Değişkenler](#değişkenler)
36 | 1. [Hoisting](#hoisting)
37 | 1. [Karşılaştırma Operatörleri](#karşılaştırma-operatörleri)
38 | 1. [Bloklar](#bloklar)
39 | 1. [Koşul İfadeleri](#koşul-ifadeleri)
40 | 1. [Yorumlar](#yorumlar)
41 | 1. [Whitespace](#whitespace)
42 | 1. [Virgüller](#virgüller)
43 | 1. [Noktalı Virgüller](#noktalı-virgüller)
44 | 1. [Tip Dönüştürme](#tip-dönüştürme)
45 | 1. [İsimlendirme](#İsimlendirme)
46 | 1. [Accessor](#accessor)
47 | 1. [Olaylar](#olaylar)
48 | 1. [jQuery](#jquery)
49 | 1. [ECMAScript 5 Uyumluluğu](#ecmascript-5-uyumluluğu)
50 | 1. [ECMAScript 6+ (ES 2015+) Özellikleri](#ecmascript-6-es-2015-Özellikleri)
51 | 1. [Yerleşik Kütüphaneler](#yerleşik-kütüphaneler)
52 | 1. [Test](#test)
53 | 1. [Performans](#performans)
54 | 1. [Kaynaklar](#kaynaklar)
55 | 1. [Organizasyonlar](#organizasyonlar)
56 | 1. [Çeviri](#Çeviri)
57 | 1. [Kılavuz Kılavuzu](#kılavuz-kılavuzu)
58 | 1. [JavaScript Sohbet Kanalı](#javascript-sohbet-kanalı)
59 | 1. [Katkıda Bulunanlar](#katkıda-bulunanlar)
60 | 1. [Lisans](#lisans)
61 | 1. [Değişiklikler](#değişiklikler)
62 |
63 | ## Veri Türleri
64 |
65 |
66 | - [1.1](#types--primitives) **Birincil**: Birincil(İlkel) bir türe eriştiğinizde doğrudan değer ile karşılaşırsınız.
67 |
68 | - `string`
69 | - `number`
70 | - `boolean`
71 | - `null`
72 | - `undefined`
73 | - `symbol`
74 |
75 | ```javascript
76 | const foo = 1;
77 | let bar = foo;
78 |
79 | bar = 9;
80 |
81 | console.log(foo, bar); // => 1, 9
82 | ```
83 |
84 | - 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.
85 |
86 |
87 | - [1.2](#types--complex) **Bileşik**: Bileşik(başvuru) türlerde değere erişmek için referans değerler ile çalışırsınız.
88 |
89 | - `object`
90 | - `array`
91 | - `function`
92 |
93 | ```javascript
94 | const foo = [1, 2];
95 | const bar = foo;
96 |
97 | bar[0] = 9;
98 |
99 | console.log(foo[0], bar[0]); // => 9, 9
100 | ```
101 |
102 | **[⬆ başa dön](#İçindekiler)**
103 |
104 | ## Referanslar
105 |
106 |
107 | - [2.1](#references--prefer-const) Tüm referanslarda `const` kullanın. `var` kullanmaktan kaçının. eslint: [`prefer-const`](https://eslint.org/docs/rules/prefer-const.html), [`no-const-assign`](https://eslint.org/docs/rules/no-const-assign.html)
108 |
109 | > Neden? Bu sayede referansların sonradan değiştirilmesi engellenir; olası hataların önüne geçilir, kodun anlaşılabilirliği artar.
110 |
111 | ```javascript
112 | // kötü
113 | var a = 1;
114 | var b = 2;
115 |
116 | // iyi
117 | const a = 1;
118 | const b = 2;
119 | ```
120 |
121 |
122 | - [2.2](#references--disallow-var) Eğer referansları yeniden tanımlayacaksanız, `var` yerine `let` kullanın. eslint: [`no-var`](https://eslint.org/docs/rules/no-var.html) jscs: [`disallowVar`](http://jscs.info/rule/disallowVar)
123 |
124 | > Neden? `let` block-scope `var` function-scope'dur.
125 |
126 | ```javascript
127 | // kötü
128 | var count = 1;
129 | if (true) {
130 | count += 1;
131 | }
132 |
133 | // iyi
134 | let count = 1;
135 | if (true) {
136 | count += 1;
137 | }
138 | ```
139 |
140 |
141 | - [2.3](#references--block-scope) Unutmayın; `let` ve `const`'un her ikiside block-scope'dur.
142 |
143 | ```javascript
144 | // const ve let sadece tanımlandıkları yaşam alanında erişilebilir olacaktır.
145 | {
146 | let a = 1;
147 | const b = 1;
148 | }
149 | console.log(a); // ReferenceError (Referans Hatası)
150 | console.log(b); // ReferenceError (Referans Hatası)
151 | ```
152 |
153 | **[⬆ başa dön](#İçindekiler)**
154 |
155 | ## Nesneler
156 |
157 |
158 | - [3.1](#objects--no-new) Nesne yaratırken literal sözdizimini kullanın. eslint: [`no-new-object`](https://eslint.org/docs/rules/no-new-object.html)
159 |
160 | ```javascript
161 | // kötü
162 | const item = new Object();
163 |
164 | // iyi
165 | const item = {};
166 | ```
167 |
168 |
169 | - [3.2](#es6-computed-properties) Nesnelerin property isimlerini dinamik şekilde oluştururken, property'leri block içerisinde yaratın.
170 |
171 | > Neden? Nesnenin tüm property'lerini aynı yerde tanımlayabilmenizi sağlar.
172 |
173 | ```javascript
174 |
175 | function getKey(k) {
176 | return `a key named ${k}`;
177 | }
178 |
179 | // kötü
180 | const obj = {
181 | id: 5,
182 | name: 'San Francisco',
183 | };
184 | obj[getKey('enabled')] = true;
185 |
186 | // iyi
187 | const obj = {
188 | id: 5,
189 | name: 'San Francisco',
190 | [getKey('enabled')]: true,
191 | };
192 | ```
193 |
194 |
195 | - [3.3](#es6-object-shorthand) Metodlarda shorthand tekniğini kullanın. eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
196 |
197 | ```javascript
198 | // kötü
199 | const atom = {
200 | value: 1,
201 |
202 | addValue: function (value) {
203 | return atom.value + value;
204 | },
205 | };
206 |
207 | // iyi
208 | const atom = {
209 | value: 1,
210 |
211 | addValue(value) {
212 | return atom.value + value;
213 | },
214 | };
215 | ```
216 |
217 |
218 | - [3.4](#es6-object-concise) Property'lerde de shorthand tekniğini kullanın. eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
219 |
220 | > Neden? Hem yazması hem de anlaşılması daha az zaman alır.
221 |
222 | ```javascript
223 | const lukeSkywalker = 'Luke Skywalker';
224 |
225 | // kötü
226 | const obj = {
227 | lukeSkywalker: lukeSkywalker,
228 | };
229 |
230 | // iyi
231 | const obj = {
232 | lukeSkywalker,
233 | };
234 | ```
235 |
236 |
237 | - [3.5](#objects--grouped-shorthand) Shorthand property'lerinize nesnenin en başında yer verin.
238 |
239 | > Neden? Bu şekilde hangi property'nin shorthand tekniği kullandığını anlamak kolaylaşacaktır.
240 |
241 | ```javascript
242 | const anakinSkywalker = 'Anakin Skywalker';
243 | const lukeSkywalker = 'Luke Skywalker';
244 |
245 | // kötü
246 | const obj = {
247 | episodeOne: 1,
248 | twoJediWalkIntoACantina: 2,
249 | lukeSkywalker,
250 | episodeThree: 3,
251 | mayTheFourth: 4,
252 | anakinSkywalker,
253 | };
254 |
255 | // iyi
256 | const obj = {
257 | lukeSkywalker,
258 | anakinSkywalker,
259 | episodeOne: 1,
260 | twoJediWalkIntoACantina: 2,
261 | episodeThree: 3,
262 | mayTheFourth: 4,
263 | };
264 | ```
265 |
266 |
267 | - [3.6](#objects--quoted-props) Sadece uygunsuz tanımlarda tırnak kullanın. eslint: [`quote-props`](https://eslint.org/docs/rules/quote-props.html) jscs: [`disallowQuotedKeysInObjects`](http://jscs.info/rule/disallowQuotedKeysInObjects)
268 |
269 | > 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.
270 |
271 | ```javascript
272 | // kötü
273 | const bad = {
274 | 'foo': 3,
275 | 'bar': 4,
276 | 'data-blah': 5,
277 | };
278 |
279 | // iyi
280 | const good = {
281 | foo: 3,
282 | bar: 4,
283 | 'data-blah': 5,
284 | };
285 | ```
286 |
287 |
288 | - [3.7](#objects--prototype-builtins) `hasOwnProperty`, `propertyIsEnumerable` ve `isPrototypeOf` gibi `Object.prototype` metodlarını doğrudan kullanmayın.
289 |
290 | > Neden? Bu metodlar nesnedeki property'ler tarafından gölgelenebilirler (`{ hasOwnProperty: false }`) ya da nesne null olabilir (`Object.create(null)`).
291 |
292 | ```javascript
293 | // kötü
294 | console.log(object.hasOwnProperty(key));
295 |
296 | // iyi
297 | console.log(Object.prototype.hasOwnProperty.call(object, key));
298 |
299 | // çok iyi
300 | const has = Object.prototype.hasOwnProperty; // scope'da önbelleğe alın.
301 | /* ya da */
302 | import has from 'has'; // https://www.npmjs.com/package/has
303 | // ...
304 | console.log(has.call(object, key));
305 | ```
306 |
307 |
308 | - [3.8](#objects--rest-spread) Sığ kopyalamada [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/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.
309 |
310 | ```javascript
311 | // çok kötü
312 | const original = { a: 1, b: 2 };
313 | const copy = Object.assign(original, { c: 3 }); // `original`'i de değiştirir. ಠ_ಠ
314 | delete copy.a; // burasıda.
315 |
316 | // kötü
317 | const original = { a: 1, b: 2 };
318 | const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
319 |
320 | // iyi
321 | const original = { a: 1, b: 2 };
322 | const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
323 |
324 | const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
325 | ```
326 |
327 | **[⬆ başa dön](#İçindekiler)**
328 |
329 | ## Diziler
330 |
331 |
332 | - [4.1](#arrays--literals) Dizi yaratırken literal sözdizimini kullanın. eslint: [`no-array-constructor`](https://eslint.org/docs/rules/no-array-constructor.html)
333 |
334 | ```javascript
335 | // kötü
336 | const items = new Array();
337 |
338 | // iyi
339 | const items = [];
340 | ```
341 |
342 |
343 | - [4.2](#arrays--push) Dizilere yeni elemanları doğrudan eklemek yerine [Array#push](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push)'u kullanın.
344 |
345 | ```javascript
346 | const someStack = [];
347 |
348 | // kötü
349 | someStack[someStack.length] = 'abracadabra';
350 |
351 | // iyi
352 | someStack.push('abracadabra');
353 | ```
354 |
355 |
356 | - [4.3](#es6-array-spreads) Dizileri kopyalamak için spread `...` operatörünü kullanın.
357 |
358 | ```javascript
359 | // kötü
360 | const len = items.length;
361 | const itemsCopy = [];
362 | let i;
363 |
364 | for (i = 0; i < len; i += 1) {
365 | itemsCopy[i] = items[i];
366 | }
367 |
368 | // iyi
369 | const itemsCopy = [...items];
370 | ```
371 |
372 |
373 | - [4.4](#arrays--from) Dizi-benzeri bir nesneyi diziye dönüştürürken [Array.from](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) yerine `...` spread operatörünü kullanın.
374 |
375 | ```javascript
376 | const foo = document.querySelectorAll('.foo');
377 |
378 | // iyi
379 | const nodes = Array.from(foo);
380 |
381 | // çok iyi
382 | const nodes = [...foo];
383 | ```
384 |
385 |
386 | - [4.5](#arrays--mapping) Geçici bir dizi oluşturmamak için dizi elemanlarında map kullanırken spread operatörü `...` yerine [Array.from](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) kullanın.
387 |
388 | ```javascript
389 | // kötü
390 | const baz = [...foo].map(bar);
391 |
392 | // iyi
393 | const baz = Array.from(foo, bar);
394 | ```
395 |
396 |
397 | - [4.6](#arrays--callback-return) Dizi metodlarının callback'lerinde return ifadesini kullanın. Eğer fonksiyon içeriği [8.2](#arrows--implicit-return) de olduğu gibi tek bir ifadeyi içeriyorsa return kullanılmayabilir. eslint: [`array-callback-return`](https://eslint.org/docs/rules/array-callback-return)
398 |
399 | ```javascript
400 | // iyi
401 | [1, 2, 3].map((x) => {
402 | const y = x + 1;
403 | return x * y;
404 | });
405 |
406 | // kötü
407 | [1, 2, 3].map(x => x + 1);
408 |
409 | // kötü - dönen değerin bulunmaması `acc`'nin ilk tekrardan sonra undefined olmasına neden olur
410 | [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
411 | const flatten = acc.concat(item);
412 | acc[index] = flatten;
413 | });
414 |
415 | // iyi
416 | [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
417 | const flatten = acc.concat(item);
418 | acc[index] = flatten;
419 | return flatten;
420 | });
421 |
422 | // kötü
423 | inbox.filter((msg) => {
424 | const { subject, author } = msg;
425 | if (subject === 'Mockingbird') {
426 | return author === 'Harper Lee';
427 | } else {
428 | return false;
429 | }
430 | });
431 |
432 | // iyi
433 | inbox.filter((msg) => {
434 | const { subject, author } = msg;
435 | if (subject === 'Mockingbird') {
436 | return author === 'Harper Lee';
437 | }
438 |
439 | return false;
440 | });
441 | ```
442 |
443 |
444 | - [4.7](#arrays--bracket-newline) Eğer dizide birden fazla satır varsa köşeli parantezleri açtıktan sonra ve kapatmadan önce yeni satıra geçin.
445 |
446 | ```javascript
447 | // kötü
448 | const arr = [
449 | [0, 1], [2, 3], [4, 5],
450 | ];
451 |
452 | const objectInArray = [{
453 | id: 1,
454 | }, {
455 | id: 2,
456 | }];
457 |
458 | const numberInArray = [
459 | 1, 2,
460 | ];
461 |
462 | // iyi
463 | const arr = [[0, 1], [2, 3], [4, 5]];
464 |
465 | const objectInArray = [
466 | {
467 | id: 1,
468 | },
469 | {
470 | id: 2,
471 | },
472 | ];
473 |
474 | const numberInArray = [
475 | 1,
476 | 2,
477 | ];
478 | ```
479 |
480 | **[⬆ başa dön](#İçindekiler)**
481 |
482 | ## Destructuring
483 |
484 |
485 | - [5.1](#destructuring--object) Bir nesneden birden fazla property'e erişirken destructuring tekniğini kullanın. eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring) jscs: [`requireObjectDestructuring`](http://jscs.info/rule/requireObjectDestructuring)
486 |
487 | > Neden ? Destructuring, property'ler için geçici değişkenler oluşturmanızı önler.
488 |
489 | ```javascript
490 | // kötü
491 | function getFullName(user) {
492 | const firstName = user.firstName;
493 | const lastName = user.lastName;
494 |
495 | return `${firstName} ${lastName}`;
496 | }
497 |
498 | // iyi
499 | function getFullName(user) {
500 | const { firstName, lastName } = user;
501 | return `${firstName} ${lastName}`;
502 | }
503 |
504 | // çok iyi
505 | function getFullName({ firstName, lastName }) {
506 | return `${firstName} ${lastName}`;
507 | }
508 | ```
509 |
510 |
511 | - [5.2](#destructuring--array) Dizilerde de destructuring tekniğini kullanın. eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring) jscs: [`requireArrayDestructuring`](http://jscs.info/rule/requireArrayDestructuring)
512 |
513 | ```javascript
514 | const arr = [1, 2, 3, 4];
515 |
516 | // kötü
517 | const first = arr[0];
518 | const second = arr[1];
519 |
520 | // iyi
521 | const [first, second] = arr;
522 | ```
523 |
524 |
525 | - [5.3](#destructuring--object-over-array) Birden fazla değer dönmesi durumunda diziler yerine nesneler ile destructuring yapın. jscs: [`disallowArrayDestructuringReturn`](http://jscs.info/rule/disallowArrayDestructuringReturn)
526 |
527 | > 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.
528 |
529 | ```javascript
530 | // kötü
531 | function processInput(input) {
532 | // then a miracle occurs
533 | return [left, right, top, bottom];
534 | }
535 |
536 | // çağrıyı yapan kısım dönen değerlerin sıralamasını dikkate almalıdır
537 | const [left, __, top] = processInput(input);
538 |
539 | // iyi
540 | function processInput(input) {
541 | // then a miracle occurs
542 | return { left, right, top, bottom };
543 | }
544 |
545 | // çağıran bölüm sadece ihtiyacı olanı alır
546 | const { left, top } = processInput(input);
547 | ```
548 |
549 | **[⬆ başa dön](#İçindekiler)**
550 |
551 | ## String
552 |
553 |
554 | - [6.1](#strings--quotes) String'lerde tek tırnak `''` kullanın. eslint: [`quotes`](https://eslint.org/docs/rules/quotes.html) jscs: [`validateQuoteMarks`](http://jscs.info/rule/validateQuoteMarks)
555 |
556 | ```javascript
557 | // kötü
558 | const name = "Capt. Janeway";
559 |
560 | // kötü - şablon enterpolasyon veya yeni satırlar içerir.
561 | const name = `Capt. Janeway`;
562 |
563 | // iyi
564 | const name = 'Capt. Janeway';
565 | ```
566 |
567 |
568 | - [6.2](#strings--line-length) 100 karakterden uzun string'ler satırlara bölünüp birbirine bağlanmamalıdır.
569 |
570 | > Neden? Bölünmüş string'ler ile çalışmak kodun okunabilirliğini düşürür.
571 |
572 | ```javascript
573 | // kötü
574 | const errorMessage = 'This is a super long error that was thrown because \
575 | of Batman. When you stop to think about how Batman had anything to do \
576 | with this, you would get nowhere \
577 | fast.';
578 |
579 | // kötü
580 | const errorMessage = 'This is a super long error that was thrown because ' +
581 | 'of Batman. When you stop to think about how Batman had anything to do ' +
582 | 'with this, you would get nowhere fast.';
583 |
584 | // iyi
585 | 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.';
586 | ```
587 |
588 |
589 | - [6.3](#es6-template-literals) Programlanabilir string'ler yaratırken string şablonlarını kullanın. eslint: [`prefer-template`](https://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](https://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings)
590 |
591 | > Neden? String şablonları; kısa, okunabilir, doğru sözdizimi ve string interpolasyon özelliklerine sahip bir kod betiği oluşturabilmenizi sağlar.
592 |
593 | ```javascript
594 | // kötü
595 | function sayHi(name) {
596 | return 'How are you, ' + name + '?';
597 | }
598 |
599 | // kötü
600 | function sayHi(name) {
601 | return ['How are you, ', name, '?'].join();
602 | }
603 |
604 | // kötü
605 | function sayHi(name) {
606 | return `How are you, ${ name }?`;
607 | }
608 |
609 | // iyi
610 | function sayHi(name) {
611 | return `How are you, ${name}?`;
612 | }
613 | ```
614 |
615 |
616 | - [6.4](#strings--eval) String'lerde asla `eval()` fonksiyonunu kullanmayın. Bu durum pek çok açığa neden olabilir. eslint: [`no-eval`](https://eslint.org/docs/rules/no-eval)
617 |
618 |
619 | - [6.5](#strings--escaping) String'lerde gereksiz yere tersbölü karakterlerini kullanmayın. eslint: [`no-useless-escape`](https://eslint.org/docs/rules/no-useless-escape)
620 |
621 | > Neden? Tersbölüler okunabilirliği düşürür ve sadece gerektiğinde kullanılmalıdır.
622 |
623 | ```javascript
624 | // kötü
625 | const foo = '\'this\' \i\s \"quoted\"';
626 |
627 | // iyi
628 | const foo = '\'this\' is "quoted"';
629 | const foo = `my name is '${name}'`;
630 | ```
631 |
632 | **[⬆ başa dön](#İçindekiler)**
633 |
634 | ## Fonksiyonlar
635 |
636 |
637 | - [7.1](#functions--declarations) Klasik fonksiyon tanımları yerine isimlendirilmiş fonksiyon ifadeleri kullanın. eslint: [`func-style`](https://eslint.org/docs/rules/func-style) jscs: [`disallowFunctionDeclarations`](http://jscs.info/rule/disallowFunctionDeclarations)
638 |
639 | > 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](https://github.com/airbnb/javascript/issues/794))
640 |
641 | ```javascript
642 | // kötü
643 | function foo() {
644 | // ...
645 | }
646 |
647 | // kötü
648 | const foo = function () {
649 | // ...
650 | };
651 |
652 | // iyi
653 | // Açıklayıcı isimlendirmeye değişken üzerinden ulaşılabilir
654 | const short = function longUniqueMoreDescriptiveLexicalFoo() {
655 | // ...
656 | };
657 | ```
658 |
659 |
660 | - [7.2](#functions--iife) Hemen çağrılan fonksiyonları (Immediately-invoked Function Expressions - IIFE) parantez içine alın. eslint: [`wrap-iife`](https://eslint.org/docs/rules/wrap-iife.html) jscs: [`requireParenthesesAroundIIFE`](http://jscs.info/rule/requireParenthesesAroundIIFE)
661 |
662 | > 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.
663 |
664 | ```javascript
665 | // immediately-invoked function expression (IIFE)
666 | (function () {
667 | console.log('Welcome to the Internet. Please follow me.');
668 | }());
669 | ```
670 |
671 |
672 | - [7.3](#functions--in-blocks) 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`](https://eslint.org/docs/rules/no-loop-func.html)
673 |
674 |
675 | - [7.4](#functions--note-on-blocks) **Not:** ECMA-262 `block` kavramını ifadelerin listesi şeklinde tanımlar. Fonksiyon tanımlamak bir ifade değildir.
676 |
677 | ```javascript
678 | // kötü
679 | if (currentUser) {
680 | function test() {
681 | console.log('Nope.');
682 | }
683 | }
684 |
685 | // iyi
686 | let test;
687 | if (currentUser) {
688 | test = () => {
689 | console.log('Yup.');
690 | };
691 | }
692 | ```
693 |
694 |
695 | - [7.5](#functions--arguments-shadow) Asla bir parametreye `arguments` adını vermeyin. Bu şekilde bir kullanım her fonksiyonun blok alanında bulunan `arguments` nesnesinin üzerinde kalacaktır.
696 |
697 | ```javascript
698 | // kötü
699 | function foo(name, options, arguments) {
700 | // ...
701 | }
702 |
703 | // iyi
704 | function foo(name, options, args) {
705 | // ...
706 | }
707 | ```
708 |
709 |
710 | - [7.6](#es6-rest) `arguments` yerine içeriğe rest `...` ile ulaşın. eslint: [`prefer-rest-params`](https://eslint.org/docs/rules/prefer-rest-params)
711 |
712 | > Neden? `...` ile sadece istenen argümanlara erişebilirsiniz. Ayrıca rest argümanlar dizi-benzeri `arguments`'in aksine gerçek bir dizidir.
713 |
714 | ```javascript
715 | // kötü
716 | function concatenateAll() {
717 | const args = Array.prototype.slice.call(arguments);
718 | return args.join('');
719 | }
720 |
721 | // iyi
722 | function concatenateAll(...args) {
723 | return args.join('');
724 | }
725 | ```
726 |
727 |
728 | - [7.7](#es6-default-parameters) Fonksiyon parametrelerini değiştirmek yerine varsayılan parametre sözdizimini kullanın.
729 |
730 | ```javascript
731 | // çok kötü
732 | function handleThings(opts) {
733 | // Hayır! Fonksiyon argümanları değiştirilmemeli.
734 | // Ayrıca, argüman hatalıyken bir nesneye eşitlemek açık oluşturabilir.
735 | opts = opts || {};
736 | // ...
737 | }
738 |
739 | // kötü
740 | function handleThings(opts) {
741 | if (opts === void 0) {
742 | opts = {};
743 | }
744 | // ...
745 | }
746 |
747 | // iyi
748 | function handleThings(opts = {}) {
749 | // ...
750 | }
751 | ```
752 |
753 |
754 | - [7.8](#functions--default-side-effects) Varsayılan parametrelerin yan etkilerini dikkate alın.
755 |
756 | > Neden? Kullanım amacına aykırıdır.
757 |
758 | ```javascript
759 | var b = 1;
760 | // kötü
761 | function count(a = b++) {
762 | console.log(a);
763 | }
764 | count(); // 1
765 | count(); // 2
766 | count(3); // 3
767 | count(); // 3
768 | ```
769 |
770 |
771 | - [7.9](#functions--defaults-last) Varsayılan parametreleri daima en sonda kullanın.
772 |
773 | ```javascript
774 | // kötü
775 | function handleThings(opts = {}, name) {
776 | // ...
777 | }
778 |
779 | // iyi
780 | function handleThings(name, opts = {}) {
781 | // ...
782 | }
783 | ```
784 |
785 |
786 | - [7.10](#functions--constructor) Yeni bir fonksiyon yaratmak için asla constructor'ları kullanmayın. eslint: [`no-new-func`](https://eslint.org/docs/rules/no-new-func)
787 |
788 | > Neden? Bu şekilde fonksiyon yaratmak güvenlik açıkları oluşturan eval()'e benzer bir durum oluşturur.
789 |
790 | ```javascript
791 | // kötü
792 | var add = new Function('a', 'b', 'return a + b');
793 |
794 | // kötü
795 | var subtract = Function('a', 'b', 'return a - b');
796 | ```
797 |
798 |
799 | - [7.11](#functions--signature-spacing) Fonksiyonlarda boşlukları doğru şekilde kullanın. eslint: [`space-before-function-paren`](https://eslint.org/docs/rules/space-before-function-paren) [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks)
800 |
801 | > Neden? Tutarlılık iyidir ve bu şekilde bir isim eklerken veya silerken boşluk eklemenizede silmenizede gerek kalmaz.
802 |
803 | ```javascript
804 | // kötü
805 | const f = function(){};
806 | const g = function (){};
807 | const h = function() {};
808 |
809 | // iyi
810 | const x = function () {};
811 | const y = function a() {};
812 | ```
813 |
814 |
815 | - [7.12](#functions--mutate-params) Asla parametreleri değiştirmeyin. eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)
816 |
817 | > Neden? Gelen nesneleri değiştirmek çağrıyı yapan betikte beklenmeyen yan etkilere neden olabilir.
818 |
819 | ```javascript
820 | // kötü
821 | function f1(obj) {
822 | obj.key = 1;
823 | }
824 |
825 | // iyi
826 | function f2(obj) {
827 | const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
828 | }
829 | ```
830 |
831 |
832 | - [7.13](#functions--reassign-params) Asla parametreleri yeniden tanımlamayın. eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)
833 |
834 | > 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.
835 |
836 | ```javascript
837 | // kötü
838 | function f1(a) {
839 | a = 1;
840 | // ...
841 | }
842 |
843 | function f2(a) {
844 | if (!a) { a = 1; }
845 | // ...
846 | }
847 |
848 | // iyi
849 | function f3(a) {
850 | const b = a || 1;
851 | // ...
852 | }
853 |
854 | function f4(a = 1) {
855 | // ...
856 | }
857 | ```
858 |
859 |
860 | - [7.14](#functions--spread-vs-apply) Değişken sayıda argüman alabilen (Variadic) fonksiyonlarda spread operatörünü `...` kullanmaya özen gösterin. eslint: [`prefer-spread`](https://eslint.org/docs/rules/prefer-spread)
861 |
862 | > Neden? Daha temiz bir kullanım şeklidir. İçeriği oluşturmanıza ve `new` ile `apply` kullanmanıza gerek kalmaz.
863 |
864 | ```javascript
865 | // kötü
866 | const x = [1, 2, 3, 4, 5];
867 | console.log.apply(console, x);
868 |
869 | // iyi
870 | const x = [1, 2, 3, 4, 5];
871 | console.log(...x);
872 |
873 | // kötü
874 | new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
875 |
876 | // iyi
877 | new Date(...[2016, 8, 5]);
878 | ```
879 |
880 |
881 | - [7.15](#functions--signature-invocation-indentation) Ç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.
882 |
883 | ```javascript
884 | // kötü
885 | function foo(bar,
886 | baz,
887 | quux) {
888 | // ...
889 | }
890 |
891 | // iyi
892 | function foo(
893 | bar,
894 | baz,
895 | quux,
896 | ) {
897 | // ...
898 | }
899 |
900 | // kötü
901 | console.log(foo,
902 | bar,
903 | baz);
904 |
905 | // iyi
906 | console.log(
907 | foo,
908 | bar,
909 | baz,
910 | );
911 | ```
912 |
913 | **[⬆ başa dön](#İçindekiler)**
914 |
915 | ## Arrow Fonksiyonlar
916 |
917 |
918 | - [8.1](#arrows--use-them) İsimsiz bir fonksiyon kullanırken (fonksiyon içi bir callback olarak) arrow (ok) fonksiyon notasyonunu kullanın. eslint: [`prefer-arrow-callback`](https://eslint.org/docs/rules/prefer-arrow-callback.html), [`arrow-spacing`](https://eslint.org/docs/rules/arrow-spacing.html) jscs: [`requireArrowFunctions`](http://jscs.info/rule/requireArrowFunctions)
919 |
920 | > Neden? Bu kullanım ihtiyaç duyulduğu gibi, `this` ile çalışan bir yapı oluşturur ve daha sade bir sözdizimine sahiptir.
921 |
922 | > Ne zaman kullanılmamalı? Fonksiyonun karmaşık bir işlevi bulunuyorsa isimlendirilmiş bir fonksiyon ifadesi kullanmalısınız.
923 |
924 | ```javascript
925 | // kötü
926 | [1, 2, 3].map(function (x) {
927 | const y = x + 1;
928 | return x * y;
929 | });
930 |
931 | // iyi
932 | [1, 2, 3].map((x) => {
933 | const y = x + 1;
934 | return x * y;
935 | });
936 | ```
937 |
938 |
939 | - [8.2](#arrows--implicit-return) Eğer fonksiyon içeriği yan etkisi bulunmayan tek bir [ifadeyi](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) 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`](https://eslint.org/docs/rules/arrow-parens.html), [`arrow-body-style`](https://eslint.org/docs/rules/arrow-body-style.html) jscs: [`disallowParenthesesAroundArrowParam`](http://jscs.info/rule/disallowParenthesesAroundArrowParam), [`requireShorthandArrowFunctions`](http://jscs.info/rule/requireShorthandArrowFunctions)
940 |
941 | > Neden? Fonksiyon zincirleri okunabilirliği artırır.
942 |
943 | ```javascript
944 | // kötü
945 | [1, 2, 3].map(number => {
946 | const nextNumber = number + 1;
947 | `A string containing the ${nextNumber}.`;
948 | });
949 |
950 | // iyi
951 | [1, 2, 3].map(number => `A string containing the ${number}.`);
952 |
953 | // iyi
954 | [1, 2, 3].map((number) => {
955 | const nextNumber = number + 1;
956 | return `A string containing the ${nextNumber}.`;
957 | });
958 |
959 | // iyi
960 | [1, 2, 3].map((number, index) => ({
961 | [index]: number,
962 | }));
963 |
964 | // Yan etkiler içeren implicit return
965 | function foo(callback) {
966 | const val = callback();
967 | if (val === true) {
968 | // callback true döndüğünde çalışan betik
969 | }
970 | }
971 |
972 | let bool = false;
973 |
974 | // kötü
975 | foo(() => bool = true);
976 |
977 | // iyi
978 | foo(() => {
979 | bool = true;
980 | });
981 | ```
982 |
983 |
984 | - [8.3](#arrows--paren-wrap) İfade birden fazla satır içeriyorsa okunabilirliği artırmak için parantez kullanın.
985 |
986 | > Neden? Fonksiyonun nerede başlayıp nerede bittiğini daha net şekilde gösterir.
987 |
988 | ```javascript
989 | // kötü
990 | ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
991 | httpMagicObjectWithAVeryLongName,
992 | httpMethod,
993 | )
994 | );
995 |
996 | // iyi
997 | ['get', 'post', 'put'].map(httpMethod => (
998 | Object.prototype.hasOwnProperty.call(
999 | httpMagicObjectWithAVeryLongName,
1000 | httpMethod,
1001 | )
1002 | ));
1003 | ```
1004 |
1005 |
1006 | - [8.4](#arrows--one-arg-parens) 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](https://eslint.org/docs/rules/arrow-parens#always) kullanın ya da jscs de [`disallowParenthesesAroundArrowParam`](http://jscs.info/rule/disallowParenthesesAroundArrowParam)'ı dahil etmeyin. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html) jscs: [`disallowParenthesesAroundArrowParam`](http://jscs.info/rule/disallowParenthesesAroundArrowParam)
1007 |
1008 | > Neden? Daha az görsel karmaşa.
1009 |
1010 | ```javascript
1011 | // kötü
1012 | [1, 2, 3].map((x) => x * x);
1013 |
1014 | // iyi
1015 | [1, 2, 3].map(x => x * x);
1016 |
1017 | // iyi
1018 | [1, 2, 3].map(number => (
1019 | `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
1020 | ));
1021 |
1022 | // kötü
1023 | [1, 2, 3].map(x => {
1024 | const y = x + 1;
1025 | return x * y;
1026 | });
1027 |
1028 | // iyi
1029 | [1, 2, 3].map((x) => {
1030 | const y = x + 1;
1031 | return x * y;
1032 | });
1033 | ```
1034 |
1035 |
1036 | - [8.5](#arrows--confusing) Arrow fonksiyonları (`=>`) yazarken karşılaştırma operatörleri (`<=`, `>=`) ile karıştırmamaya dikkat edin. eslint: [`no-confusing-arrow`](https://eslint.org/docs/rules/no-confusing-arrow)
1037 |
1038 | ```javascript
1039 | // kötü
1040 | const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
1041 |
1042 | // kötü
1043 | const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
1044 |
1045 | // iyi
1046 | const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
1047 |
1048 | // iyi
1049 | const itemHeight = (item) => {
1050 | const { height, largeSize, smallSize } = item;
1051 | return height > 256 ? largeSize : smallSize;
1052 | };
1053 | ```
1054 |
1055 | **[⬆ başa dön](#İçindekiler)**
1056 |
1057 | ## Sınıflar & Constructor
1058 |
1059 |
1060 | - [9.1](#constructors--use-class) Daima `class` kullanın. Doğrudan `prototype` manipulasyonundan kaçının.
1061 |
1062 | > Neden? `class` sözdizimi daha doğru ve kolaydır.
1063 |
1064 | ```javascript
1065 | // kötü
1066 | function Queue(contents = []) {
1067 | this.queue = [...contents];
1068 | }
1069 | Queue.prototype.pop = function () {
1070 | const value = this.queue[0];
1071 | this.queue.splice(0, 1);
1072 | return value;
1073 | };
1074 |
1075 | // iyi
1076 | class Queue {
1077 | constructor(contents = []) {
1078 | this.queue = [...contents];
1079 | }
1080 | pop() {
1081 | const value = this.queue[0];
1082 | this.queue.splice(0, 1);
1083 | return value;
1084 | }
1085 | }
1086 | ```
1087 |
1088 |
1089 | - [9.2](#constructors--extends) Kalıtım için `extends`'i kullanın.
1090 |
1091 | > Neden? Prototip işlevselliğini `instanceof`'u bozmadan içselleştirmenin yerleşik olarak gelen yöntemidir.
1092 |
1093 | ```javascript
1094 | // kötü
1095 | const inherits = require('inherits');
1096 | function PeekableQueue(contents) {
1097 | Queue.apply(this, contents);
1098 | }
1099 | inherits(PeekableQueue, Queue);
1100 | PeekableQueue.prototype.peek = function () {
1101 | return this.queue[0];
1102 | };
1103 |
1104 | // iyi
1105 | class PeekableQueue extends Queue {
1106 | peek() {
1107 | return this.queue[0];
1108 | }
1109 | }
1110 | ```
1111 |
1112 |
1113 | - [9.3](#constructors--chaining) Metodlar, metod zincirleri için `this` return edebilir.
1114 |
1115 | ```javascript
1116 | // kötü
1117 | Jedi.prototype.jump = function () {
1118 | this.jumping = true;
1119 | return true;
1120 | };
1121 |
1122 | Jedi.prototype.setHeight = function (height) {
1123 | this.height = height;
1124 | };
1125 |
1126 | const luke = new Jedi();
1127 | luke.jump(); // => true
1128 | luke.setHeight(20); // => undefined
1129 |
1130 | // iyi
1131 | class Jedi {
1132 | jump() {
1133 | this.jumping = true;
1134 | return this;
1135 | }
1136 |
1137 | setHeight(height) {
1138 | this.height = height;
1139 | return this;
1140 | }
1141 | }
1142 |
1143 | const luke = new Jedi();
1144 |
1145 | luke.jump()
1146 | .setHeight(20);
1147 | ```
1148 |
1149 |
1150 | - [9.4](#constructors--tostring) Özel toString() metodları yazılabilir fakat doğru şekilde çalıştığına ve yan etkiler oluşturmadığına emin olunmalıdır.
1151 |
1152 | ```javascript
1153 | class Jedi {
1154 | constructor(options = {}) {
1155 | this.name = options.name || 'no name';
1156 | }
1157 |
1158 | getName() {
1159 | return this.name;
1160 | }
1161 |
1162 | toString() {
1163 | return `Jedi - ${this.getName()}`;
1164 | }
1165 | }
1166 | ```
1167 |
1168 |
1169 | - [9.5](#constructors--no-useless) 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`](https://eslint.org/docs/rules/no-useless-constructor)
1170 |
1171 | ```javascript
1172 | // kötü
1173 | class Jedi {
1174 | constructor() {}
1175 |
1176 | getName() {
1177 | return this.name;
1178 | }
1179 | }
1180 |
1181 | // kötü
1182 | class Rey extends Jedi {
1183 | constructor(...args) {
1184 | super(...args);
1185 | }
1186 | }
1187 |
1188 | // iyi
1189 | class Rey extends Jedi {
1190 | constructor(...args) {
1191 | super(...args);
1192 | this.name = 'Rey';
1193 | }
1194 | }
1195 | ```
1196 |
1197 |
1198 | - [9.6](#classes--no-duplicate-members) Sınıf üyelerini tekrarlamaktan kaçının. eslint: [`no-dupe-class-members`](https://eslint.org/docs/rules/no-dupe-class-members)
1199 |
1200 | > Neden? Sınıf üyelerinin tekrar deklare edilmesi durumunda son tekrarlanan üye dikkate alınır.
1201 |
1202 | ```javascript
1203 | // kötü
1204 | class Foo {
1205 | bar() { return 1; }
1206 | bar() { return 2; }
1207 | }
1208 |
1209 | // iyi
1210 | class Foo {
1211 | bar() { return 1; }
1212 | }
1213 |
1214 | // iyi
1215 | class Foo {
1216 | bar() { return 2; }
1217 | }
1218 | ```
1219 |
1220 | **[⬆ başa dön](#İçindekiler)**
1221 |
1222 | ## Modüller
1223 |
1224 |
1225 | - [10.1](#modules--use-them) Standart bir yapıya sahip olmayan modül sistemlerinizde daima (`import`/`export`) kullanın. İstediğinizde tercih ettiğiniz modül sistemine (transpile) çevirebilirsiniz.
1226 |
1227 | > Neden? Modüller geleceğin teknolojisidir. Şimdiden kullanmaya başlamalısınız.
1228 |
1229 | ```javascript
1230 | // kötü
1231 | const AirbnbStyleGuide = require('./AirbnbStyleGuide');
1232 | module.exports = AirbnbStyleGuide.es6;
1233 |
1234 | // normal
1235 | import AirbnbStyleGuide from './AirbnbStyleGuide';
1236 | export default AirbnbStyleGuide.es6;
1237 |
1238 | // iyi
1239 | import { es6 } from './AirbnbStyleGuide';
1240 | export default es6;
1241 | ```
1242 |
1243 |
1244 | - [10.2](#modules--no-wildcard) Wildcard import'ları kullanmayın.
1245 |
1246 | > Neden? Böylece tek bir default export'unuz bulunacaktır.
1247 |
1248 | ```javascript
1249 | // kötü
1250 | import * as AirbnbStyleGuide from './AirbnbStyleGuide';
1251 |
1252 | // iyi
1253 | import AirbnbStyleGuide from './AirbnbStyleGuide';
1254 | ```
1255 |
1256 |
1257 | - [10.3](#modules--no-export-from-import) Import üzerinden direkt export etmeyin.
1258 |
1259 | > 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.
1260 |
1261 | ```javascript
1262 | // kötü
1263 | // filename es6.js
1264 | export { es6 as default } from './AirbnbStyleGuide';
1265 |
1266 | // iyi
1267 | // filename es6.js
1268 | import { es6 } from './AirbnbStyleGuide';
1269 | export default es6;
1270 | ```
1271 |
1272 |
1273 | - [10.4](#modules--no-duplicate-imports) Aynı path üzerindeki tüm import'ları aynı yerde yapın.
1274 | eslint: [`no-duplicate-imports`](https://eslint.org/docs/rules/no-duplicate-imports)
1275 | > Neden? Aynı path üzerinden farklı konumlarda import kullanmak kodun geliştirilmesini zorlaştıracaktır.
1276 |
1277 | ```javascript
1278 | // kötü
1279 | import foo from 'foo';
1280 | // … diğer import'lar … //
1281 | import { named1, named2 } from 'foo';
1282 |
1283 | // iyi
1284 | import foo, { named1, named2 } from 'foo';
1285 |
1286 | // iyi
1287 | import foo, {
1288 | named1,
1289 | named2,
1290 | } from 'foo';
1291 | ```
1292 |
1293 |
1294 | - [10.5](#modules--no-mutable-exports) Değiştirilebilir binding'leri export etmeyin.
1295 | eslint: [`import/no-mutable-exports`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md)
1296 | > 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.
1297 |
1298 | ```javascript
1299 | // kötü
1300 | let foo = 3;
1301 | export { foo };
1302 |
1303 | // iyi
1304 | const foo = 3;
1305 | export { foo };
1306 | ```
1307 |
1308 |
1309 | - [10.6](#modules--prefer-default-export) Tek bir export'a sahip modüllerde isimlendirilmiş export yerine default export kullanın.
1310 | eslint: [`import/prefer-default-export`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md)
1311 | > Neden? Tek bir export kullandığınız modüllerde default kullanımı okunabilirliği ve geliştirilebilirliği artırır.
1312 |
1313 | ```javascript
1314 | // bad
1315 | export function foo() {}
1316 |
1317 | // good
1318 | export default function foo() {}
1319 | ```
1320 |
1321 |
1322 | - [10.7](#modules--imports-first) Tüm `import`'ları diğer ifadelerin üzerinde kullanın.
1323 | eslint: [`import/first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md)
1324 | > Neden? `import` kullanımından doğabilecek aksilikleri önleyecektir.
1325 |
1326 | ```javascript
1327 | // kötü
1328 | import foo from 'foo';
1329 | foo.init();
1330 |
1331 | import bar from 'bar';
1332 |
1333 | // iyi
1334 | import foo from 'foo';
1335 | import bar from 'bar';
1336 |
1337 | foo.init();
1338 | ```
1339 |
1340 |
1341 | - [10.8](#modules--multiline-imports-over-newlines) Import'lar tıpkı çok satırlı diziler ve çok satırlı sabitler gibi kullanılmalıdır.
1342 |
1343 | > Neden? Süslü parantezlere sahip bloklar stil rehberinin tamamında aynı yazım kurallarına sahiptir.
1344 |
1345 | ```javascript
1346 | // kötü
1347 | import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
1348 |
1349 | // iyi
1350 | import {
1351 | longNameA,
1352 | longNameB,
1353 | longNameC,
1354 | longNameD,
1355 | longNameE,
1356 | } from 'path';
1357 | ```
1358 |
1359 |
1360 | - [10.9](#modules--no-webpack-loader-syntax) Modül import ifadelerinde webpack loader sözdizimini kullanmayın.
1361 | eslint: [`import/no-webpack-loader-syntax`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md)
1362 | > Neden? Webpack sözdizimi module bundler'da importları çoğaltır. Bunun yerine loader sözdizimini `webpack.config.js` içerisinde kullanın.
1363 |
1364 | ```javascript
1365 | // kötü
1366 | import fooSass from 'css!sass!foo.scss';
1367 | import barCss from 'style!css!bar.css';
1368 |
1369 | // iyi
1370 | import fooSass from 'foo.scss';
1371 | import barCss from 'bar.css';
1372 | ```
1373 |
1374 | **[⬆ başa dön](#İçindekiler)**
1375 |
1376 | ## Yineleyiciler ve Oluşturucular
1377 |
1378 |
1379 | - [11.1](#iterators--nope) Yineleyici (Iterator) kullanmayın. `for-in` ve `for-of` gibi döngülerde higher-order fonksiyonları tercih edin. eslint: [`no-iterator`](https://eslint.org/docs/rules/no-iterator.html) [`no-restricted-syntax`](https://eslint.org/docs/rules/no-restricted-syntax)
1380 |
1381 | > Neden? Değerleri return eden sade fonksiyonların kullanılması yan etkileri önler ve bu kullanım şekli en önemli kurallardandır.
1382 |
1383 | > 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.
1384 |
1385 | ```javascript
1386 | const numbers = [1, 2, 3, 4, 5];
1387 |
1388 | // kötü
1389 | let sum = 0;
1390 | for (let num of numbers) {
1391 | sum += num;
1392 | }
1393 | sum === 15;
1394 |
1395 | // iyi
1396 | let sum = 0;
1397 | numbers.forEach((num) => {
1398 | sum += num;
1399 | });
1400 | sum === 15;
1401 |
1402 | // çok iyi
1403 | const sum = numbers.reduce((total, num) => total + num, 0);
1404 | sum === 15;
1405 |
1406 | // kötü
1407 | const increasedByOne = [];
1408 | for (let i = 0; i < numbers.length; i++) {
1409 | increasedByOne.push(numbers[i] + 1);
1410 | }
1411 |
1412 | // iyi
1413 | const increasedByOne = [];
1414 | numbers.forEach((num) => {
1415 | increasedByOne.push(num + 1);
1416 | });
1417 |
1418 | // çok iyi
1419 | const increasedByOne = numbers.map(num => num + 1);
1420 | ```
1421 |
1422 |
1423 | - [11.2](#generators--nope) Şimdilik oluşturucu (generator) kullanmayın.
1424 |
1425 | > Neden? ES5'e doğru şekilde transpile edilemezler.
1426 |
1427 |
1428 | - [11.3](#generators--spacing) Eğer oluşturucu kullanmanız gerekiyorsa, ya da [önerimizi](#generators--nope) 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`](https://eslint.org/docs/rules/generator-star-spacing)
1429 |
1430 | > Neden? `function` ve `*` kavramsal terimlerdir. `*`, `function` için bir niteleyici değildir. `function*`, `function`'ın aksine eşsiz bir construct'tır.
1431 |
1432 | ```javascript
1433 | // kötü
1434 | function * foo() {
1435 | // ...
1436 | }
1437 |
1438 | // kötü
1439 | const bar = function * () {
1440 | // ...
1441 | };
1442 |
1443 | // kötü
1444 | const baz = function *() {
1445 | // ...
1446 | };
1447 |
1448 | // kötü
1449 | const quux = function*() {
1450 | // ...
1451 | };
1452 |
1453 | // kötü
1454 | function*foo() {
1455 | // ...
1456 | }
1457 |
1458 | // kötü
1459 | function *foo() {
1460 | // ...
1461 | }
1462 |
1463 | // çok kötü
1464 | function
1465 | *
1466 | foo() {
1467 | // ...
1468 | }
1469 |
1470 | // çok kötü
1471 | const wat = function
1472 | *
1473 | () {
1474 | // ...
1475 | };
1476 |
1477 | // iyi
1478 | function* foo() {
1479 | // ...
1480 | }
1481 |
1482 | // iyi
1483 | const foo = function* () {
1484 | // ...
1485 | };
1486 | ```
1487 |
1488 | **[⬆ başa dön](#İçindekiler)**
1489 |
1490 | ## Property
1491 |
1492 |
1493 | - [12.1](#properties--dot) Property'lere erişirken nokta notasyonunu kullanın. eslint: [`dot-notation`](https://eslint.org/docs/rules/dot-notation.html) jscs: [`requireDotNotation`](http://jscs.info/rule/requireDotNotation)
1494 |
1495 | ```javascript
1496 | const luke = {
1497 | jedi: true,
1498 | age: 28,
1499 | };
1500 |
1501 | // kötü
1502 | const isJedi = luke['jedi'];
1503 |
1504 | // iyi
1505 | const isJedi = luke.jedi;
1506 | ```
1507 |
1508 |
1509 | - [12.2](#properties--bracket) Bir değişken ile property'lere erişirken köşeli parantez `[]` kullanın.
1510 |
1511 | ```javascript
1512 | const luke = {
1513 | jedi: true,
1514 | age: 28,
1515 | };
1516 |
1517 | function getProp(prop) {
1518 | return luke[prop];
1519 | }
1520 |
1521 | const isJedi = getProp('jedi');
1522 | ```
1523 |
1524 | - [12.3](#es2016-properties--exponentiation-operator) Üstalma hesaplamalarında üstalma `**` operaötürünü kullanın. eslint: [`no-restricted-properties`](https://eslint.org/docs/rules/no-restricted-properties).
1525 |
1526 | ```javascript
1527 | // kötü
1528 | const binary = Math.pow(2, 10);
1529 |
1530 | // iyi
1531 | const binary = 2 ** 10;
1532 | ```
1533 |
1534 | **[⬆ başa dön](#İçindekiler)**
1535 |
1536 | ## Değişkenler
1537 |
1538 |
1539 | - [13.1](#variables--const) 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`](https://eslint.org/docs/rules/no-undef) [`prefer-const`](https://eslint.org/docs/rules/prefer-const)
1540 |
1541 | ```javascript
1542 | // kötü
1543 | superPower = new SuperPower();
1544 |
1545 | // iyi
1546 | const superPower = new SuperPower();
1547 | ```
1548 |
1549 |
1550 | - [13.2](#variables--one-const) Her değişken ayrı ayrı `const` ya da `let` kullanın. eslint: [`one-var`](https://eslint.org/docs/rules/one-var.html) jscs: [`disallowMultipleVarDecl`](http://jscs.info/rule/disallowMultipleVarDecl)
1551 |
1552 | > 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.
1553 |
1554 | ```javascript
1555 | // kötü
1556 | const items = getItems(),
1557 | goSportsTeam = true,
1558 | dragonball = 'z';
1559 |
1560 | // kötü
1561 | // (yukarıdaki ile kıyaslayarak yazım hatasını bulun)
1562 | const items = getItems(),
1563 | goSportsTeam = true;
1564 | dragonball = 'z';
1565 |
1566 | // iyi
1567 | const items = getItems();
1568 | const goSportsTeam = true;
1569 | const dragonball = 'z';
1570 | ```
1571 |
1572 |
1573 | - [13.3](#variables--const-let-group) Önce `const` sonra `let` değişkenlerini gruplayın.
1574 |
1575 | > Neden? Bu şekilde daha önce tanımlanmış bir değişkeni farklı bir değişkene atamak daha kolaydır.
1576 |
1577 | ```javascript
1578 | // kötü
1579 | let i, len, dragonball,
1580 | items = getItems(),
1581 | goSportsTeam = true;
1582 |
1583 | // kötü
1584 | let i;
1585 | const items = getItems();
1586 | let dragonball;
1587 | const goSportsTeam = true;
1588 | let len;
1589 |
1590 | // iyi
1591 | const goSportsTeam = true;
1592 | const items = getItems();
1593 | let dragonball;
1594 | let i;
1595 | let length;
1596 | ```
1597 |
1598 |
1599 | - [13.4](#variables--define-where-used) Değişkenleri kullanmanız gereken yerlerde tanımlayın ancak kabul edilebilir bir alanda oluşturun.
1600 |
1601 | > Neden? `let` ve `const` fonksiyon scope'da değil block scope'da çalışır.
1602 |
1603 | ```javascript
1604 | // kötü
1605 | function checkName(hasName) {
1606 | const name = getName();
1607 |
1608 | if (hasName === 'test') {
1609 | return false;
1610 | }
1611 |
1612 | if (name === 'test') {
1613 | this.setName('');
1614 | return false;
1615 | }
1616 |
1617 | return name;
1618 | }
1619 |
1620 | // iyi
1621 | function checkName(hasName) {
1622 | if (hasName === 'test') {
1623 | return false;
1624 | }
1625 |
1626 | const name = getName();
1627 |
1628 | if (name === 'test') {
1629 | this.setName('');
1630 | return false;
1631 | }
1632 |
1633 | return name;
1634 | }
1635 | ```
1636 |
1637 | - [13.5](#variables--no-chain-assignment) Değişken tanımlarında zincir tekniğini kullanmayın. eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)
1638 |
1639 | > Neden? Zincirleyerek oluşturmak, global değişkenler üretir.
1640 |
1641 | ```javascript
1642 | // kötü
1643 | (function example() {
1644 | // JavaScript işlemi aşağıdaki gibi ele alır.
1645 | // let a = ( b = ( c = 1 ) );
1646 | // let, sadece a'da uygulanır; b ve c
1647 | // global değişkenler olacaktır.
1648 | let a = b = c = 1;
1649 | }());
1650 |
1651 | console.log(a); // ReferenceError
1652 | console.log(b); // 1
1653 | console.log(c); // 1
1654 |
1655 | // iyi
1656 | (function example() {
1657 | let a = 1;
1658 | let b = a;
1659 | let c = a;
1660 | }());
1661 |
1662 | console.log(a); // ReferenceError
1663 | console.log(b); // ReferenceError
1664 | console.log(c); // ReferenceError
1665 |
1666 | // aynı şey `const` için de geçerlidir
1667 | ```
1668 |
1669 |
1670 | - [13.6](#variables--unary-increment-decrement) Eksiltme ve artırma operatörlerini kullanmaktan kaçının. (++, --). eslint [`no-plusplus`](https://eslint.org/docs/rules/no-plusplus)
1671 |
1672 | > 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.
1673 |
1674 | ```javascript
1675 | // kötü
1676 |
1677 | const array = [1, 2, 3];
1678 | let num = 1;
1679 | num++;
1680 | --num;
1681 |
1682 | let sum = 0;
1683 | let truthyCount = 0;
1684 | for (let i = 0; i < array.length; i++) {
1685 | let value = array[i];
1686 | sum += value;
1687 | if (value) {
1688 | truthyCount++;
1689 | }
1690 | }
1691 |
1692 | // iyi
1693 |
1694 | const array = [1, 2, 3];
1695 | let num = 1;
1696 | num += 1;
1697 | num -= 1;
1698 |
1699 | const sum = array.reduce((a, b) => a + b, 0);
1700 | const truthyCount = array.filter(Boolean).length;
1701 | ```
1702 |
1703 |
1704 | - [13.7](#variables--linebreak) Tanımlama işlemlerinde `=`'den sonra satır atlamayın. Eğer tanım [`max-len`](https://eslint.org/docs/rules/max-len.html) hatasına neden oluyorsa değeri paranteze alın. eslint [`operator-linebreak`](https://eslint.org/docs/rules/operator-linebreak.html).
1705 |
1706 | > Neden? Satır atlamak `=`'de hataya neden olabilir.
1707 |
1708 | ```javascript
1709 | // kötü
1710 | const foo =
1711 | superLongLongLongLongLongLongLongLongFunctionName();
1712 |
1713 | // kötü
1714 | const foo
1715 | = 'superLongLongLongLongLongLongLongLongString';
1716 |
1717 | // iyi
1718 | const foo = (
1719 | superLongLongLongLongLongLongLongLongFunctionName()
1720 | );
1721 |
1722 | // iyi
1723 | const foo = 'superLongLongLongLongLongLongLongLongString';
1724 | ```
1725 |
1726 | **[⬆ başa dön](#İçindekiler)**
1727 |
1728 | ## Hoisting
1729 |
1730 |
1731 | - [14.1](#hoisting--about) `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)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) adlı yeni bir konsept ile çalışır. [typeof kullanımı artık sağlıklı değildir](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15) .
1732 |
1733 | ```javascript
1734 | // bu bölüm çalışmayacaktır (notDefined adlı
1735 | // bir global değişken olmadığı için)
1736 | function example() {
1737 | console.log(notDefined); // => ReferenceError
1738 | }
1739 |
1740 | // referansı atanmış değişkenler
1741 | // hoisting'den ötürü çalışırlar. Not: atanan değer
1742 | // hoisted edilmeyecektir.
1743 | function example() {
1744 | console.log(declaredButNotAssigned); // => undefined
1745 | var declaredButNotAssigned = true;
1746 | }
1747 |
1748 | // interpreter değişkeni hoist edecek ve
1749 | // tanımı scope'un tepesine çıkaracaktır.
1750 | // yani yukarıdaki örnek aşağıdaki şekilde
1751 | // yeniden yazılabilir.
1752 | function example() {
1753 | let declaredButNotAssigned;
1754 | console.log(declaredButNotAssigned); // => undefined
1755 | declaredButNotAssigned = true;
1756 | }
1757 |
1758 | // let ve const ile
1759 | function example() {
1760 | console.log(declaredButNotAssigned); // => throws a ReferenceError
1761 | console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
1762 | const declaredButNotAssigned = true;
1763 | }
1764 | ```
1765 |
1766 |
1767 | - [14.2](#hoisting--anon-expressions) Anonim fonksiyon ifadelerinde isim yukarı taşınsada içerik taşınmaz.
1768 |
1769 | ```javascript
1770 | function example() {
1771 | console.log(anonymous); // => undefined
1772 |
1773 | anonymous(); // => TypeError anonymous is not a function
1774 |
1775 | var anonymous = function () {
1776 | console.log('anonymous function expression');
1777 | };
1778 | }
1779 | ```
1780 |
1781 |
1782 | - [14.3](#hoisting--named-expressions) Atanmış fonksiyon ifadelerinde değişken adı yukarı taşınsada, içerik ya da fonksiyon adı taşınmaz.
1783 |
1784 | ```javascript
1785 | function example() {
1786 | console.log(named); // => undefined
1787 |
1788 | named(); // => TypeError named is not a function
1789 |
1790 | superPower(); // => ReferenceError superPower is not defined
1791 |
1792 | var named = function superPower() {
1793 | console.log('Flying');
1794 | };
1795 | }
1796 |
1797 | // fonksiyon ile değişken adı aynı olduğunda da
1798 | // aynı durum geçerlidir.
1799 | function example() {
1800 | console.log(named); // => undefined
1801 |
1802 | named(); // => TypeError named is not a function
1803 |
1804 | var named = function named() {
1805 | console.log('named');
1806 | };
1807 | }
1808 | ```
1809 |
1810 |
1811 | - [14.4](#hoisting--declarations) Fonksiyon bildirimlerinde (tanımlarında) içerik ve isim yukarı taşınır.
1812 |
1813 | ```javascript
1814 | function example() {
1815 | superPower(); // => Flying
1816 |
1817 | function superPower() {
1818 | console.log('Flying');
1819 | }
1820 | }
1821 | ```
1822 |
1823 | - Daha fazla bilgi için [Ben Cherry](http://www.adequatelygood.com/)'nin kaleme aldığı [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/) yazısı okunabilir.
1824 |
1825 | **[⬆ başa dön](#İçindekiler)**
1826 |
1827 | ## Karşılaştırma Operatörleri
1828 |
1829 |
1830 | - [15.1](#comparison--eqeqeq) `==` ve `!=` yerine `===` ve `!==` kullanın. eslint: [`eqeqeq`](https://eslint.org/docs/rules/eqeqeq.html)
1831 |
1832 |
1833 | - [15.2](#comparison--if) `if` gibi koşullu ifadelerinde `ToBoolean` metodu aşağıdaki kurallar ile uygulanır:
1834 |
1835 | - **Objects**, **true** ile değerlendirilir.
1836 | - **Undefined**, **false** ile değerlendirilir.
1837 | - **Null**, **false** ile değerlendirilir.
1838 | - **Booleans**, **the value of the boolean** ile değerlendirilir.
1839 | - **Numbers**, **+0, -0, or NaN** için **false**, aksi halde **true** ile değerlendirilir.
1840 | - **Strings**, boş `''` ise **false**, aksi halde **true** ile değerlendirilir.
1841 |
1842 | ```javascript
1843 | if ([0] && []) {
1844 | // true
1845 | // dizi (boş dahi olsa) bir nesnedir, nesneler true ile değerlenir.
1846 | }
1847 | ```
1848 |
1849 |
1850 | - [15.3](#comparison--shortcuts) Boolean için kısayolları kullanabilirsiniz ancak string ve number türlerinde kullanmamalısınız.
1851 |
1852 | ```javascript
1853 | // kötü
1854 | if (isValid === true) {
1855 | // ...
1856 | }
1857 |
1858 | // iyi
1859 | if (isValid) {
1860 | // ...
1861 | }
1862 |
1863 | // kötü
1864 | if (name) {
1865 | // ...
1866 | }
1867 |
1868 | // iyi
1869 | if (name !== '') {
1870 | // ...
1871 | }
1872 |
1873 | // kötü
1874 | if (collection.length) {
1875 | // ...
1876 | }
1877 |
1878 | // iyi
1879 | if (collection.length > 0) {
1880 | // ...
1881 | }
1882 | ```
1883 |
1884 |
1885 | - [15.4](#comparison--moreinfo) Daha fazla bilgi için Angus Croll tarafından kaleme alınan [Truth Equality and JavaScript](https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) adlı yazısını inceleyin.
1886 |
1887 |
1888 | - [15.5](#comparison--switch-blocks) 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`](https://eslint.org/docs/rules/no-case-declarations.html)
1889 |
1890 | > 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.
1891 |
1892 | ```javascript
1893 | // kötü
1894 | switch (foo) {
1895 | case 1:
1896 | let x = 1;
1897 | break;
1898 | case 2:
1899 | const y = 2;
1900 | break;
1901 | case 3:
1902 | function f() {
1903 | // ...
1904 | }
1905 | break;
1906 | default:
1907 | class C {}
1908 | }
1909 |
1910 | // iyi
1911 | switch (foo) {
1912 | case 1: {
1913 | let x = 1;
1914 | break;
1915 | }
1916 | case 2: {
1917 | const y = 2;
1918 | break;
1919 | }
1920 | case 3: {
1921 | function f() {
1922 | // ...
1923 | }
1924 | break;
1925 | }
1926 | case 4:
1927 | bar();
1928 | break;
1929 | default: {
1930 | class C {}
1931 | }
1932 | }
1933 | ```
1934 |
1935 |
1936 | - [15.6](#comparison--nested-ternaries) Ternary operatörler tek satırda yazılmalıdır ve nested kullanımdan kaçınılmalıdır. eslint: [`no-nested-ternary`](https://eslint.org/docs/rules/no-nested-ternary.html)
1937 |
1938 | ```javascript
1939 | // kötü
1940 | const foo = maybe1 > maybe2
1941 | ? "bar"
1942 | : value1 > value2 ? "baz" : null;
1943 |
1944 | // 2 ayrı ifadeye bölünür
1945 | const maybeNull = value1 > value2 ? 'baz' : null;
1946 |
1947 | // iyi
1948 | const foo = maybe1 > maybe2
1949 | ? 'bar'
1950 | : maybeNull;
1951 |
1952 | // çok iyi
1953 | const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
1954 | ```
1955 |
1956 |
1957 | - [15.7](#comparison--unneeded-ternary) Gereksiz ternary ifadelerden kaçınılmalıdır. eslint: [`no-unneeded-ternary`](https://eslint.org/docs/rules/no-unneeded-ternary.html)
1958 |
1959 | ```javascript
1960 | // kötü
1961 | const foo = a ? a : b;
1962 | const bar = c ? true : false;
1963 | const baz = c ? false : true;
1964 |
1965 | // iyi
1966 | const foo = a || b;
1967 | const bar = !!c;
1968 | const baz = !c;
1969 | ```
1970 |
1971 |
1972 | - [15.8](#comparison--no-mixed-operators) 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`](https://eslint.org/docs/rules/no-mixed-operators.html)
1973 |
1974 | > Neden? Bu kullanım okunabilirliği artırır ve ifadeyi daha anlaşılır kılar.
1975 |
1976 | ```javascript
1977 | // kötü
1978 | const foo = a && b < 0 || c > 0 || d + 1 === 0;
1979 |
1980 | // kötü
1981 | const bar = a ** b - 5 % d;
1982 |
1983 | // kötü
1984 | // karıştırılabilir (a || b) && c
1985 | if (a || b && c) {
1986 | return d;
1987 | }
1988 |
1989 | // iyi
1990 | const foo = (a && b < 0) || c > 0 || (d + 1 === 0);
1991 |
1992 | // iyi
1993 | const bar = (a ** b) - (5 % d);
1994 |
1995 | // iyi
1996 | if (a || (b && c)) {
1997 | return d;
1998 | }
1999 |
2000 | // iyi
2001 | const bar = a + b / c * d;
2002 | ```
2003 |
2004 | **[⬆ başa dön](#İçindekiler)**
2005 |
2006 | ## Bloklar
2007 |
2008 |
2009 | - [16.1](#blocks--braces) Çok satırlı blokların tamamında süslü parantez kullanın. eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)
2010 |
2011 | ```javascript
2012 | // kötü
2013 | if (test)
2014 | return false;
2015 |
2016 | // iyi
2017 | if (test) return false;
2018 |
2019 | // iyi
2020 | if (test) {
2021 | return false;
2022 | }
2023 |
2024 | // kötü
2025 | function foo() { return false; }
2026 |
2027 | // iyi
2028 | function bar() {
2029 | return false;
2030 | }
2031 | ```
2032 |
2033 |
2034 | - [16.2](#blocks--cuddled-elses) `if` ve `else` içeren çok satırlı bloklarda, `else`'i `if` bloğunun kapandığı satırda başlatın. eslint: [`brace-style`](https://eslint.org/docs/rules/brace-style.html) jscs: [`disallowNewlineBeforeBlockStatements`](http://jscs.info/rule/disallowNewlineBeforeBlockStatements)
2035 |
2036 | ```javascript
2037 | // kötü
2038 | if (test) {
2039 | thing1();
2040 | thing2();
2041 | }
2042 | else {
2043 | thing3();
2044 | }
2045 |
2046 | // iyi
2047 | if (test) {
2048 | thing1();
2049 | thing2();
2050 | } else {
2051 | thing3();
2052 | }
2053 | ```
2054 |
2055 |
2056 | - [16.3](#blocks--no-else-return) 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`](https://eslint.org/docs/rules/no-else-return)
2057 |
2058 | ```javascript
2059 | // kötü
2060 | function foo() {
2061 | if (x) {
2062 | return x;
2063 | } else {
2064 | return y;
2065 | }
2066 | }
2067 |
2068 | // kötü
2069 | function cats() {
2070 | if (x) {
2071 | return x;
2072 | } else if (y) {
2073 | return y;
2074 | }
2075 | }
2076 |
2077 | // kötü
2078 | function dogs() {
2079 | if (x) {
2080 | return x;
2081 | } else {
2082 | if (y) {
2083 | return y;
2084 | }
2085 | }
2086 | }
2087 |
2088 | // iyi
2089 | function foo() {
2090 | if (x) {
2091 | return x;
2092 | }
2093 |
2094 | return y;
2095 | }
2096 |
2097 | // iyi
2098 | function cats() {
2099 | if (x) {
2100 | return x;
2101 | }
2102 |
2103 | if (y) {
2104 | return y;
2105 | }
2106 | }
2107 |
2108 | //iyi
2109 | function dogs(x) {
2110 | if (x) {
2111 | if (z) {
2112 | return y;
2113 | }
2114 | } else {
2115 | return z;
2116 | }
2117 | }
2118 | ```
2119 |
2120 | **[⬆ başa dön](#İçindekiler)**
2121 |
2122 | ## Koşul İfadeleri
2123 |
2124 |
2125 | - [17.1](#control-statements) 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.
2126 |
2127 | > Neden? Karmaşık yapıyı sadeleştirerek okunabilirliği artıracaktır. Ayrıca metod zincirlerine benzer bir kalıptır.
2128 |
2129 | ```javascript
2130 | // kötü
2131 | if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {
2132 | thing1();
2133 | }
2134 |
2135 | // kötü
2136 | if (foo === 123 &&
2137 | bar === 'abc') {
2138 | thing1();
2139 | }
2140 |
2141 | // kötü
2142 | if (foo === 123
2143 | && bar === 'abc') {
2144 | thing1();
2145 | }
2146 |
2147 | // kötü
2148 | if (
2149 | foo === 123 &&
2150 | bar === 'abc'
2151 | ) {
2152 | thing1();
2153 | }
2154 |
2155 | // iyi
2156 | if (
2157 | foo === 123
2158 | && bar === 'abc'
2159 | ) {
2160 | thing1();
2161 | }
2162 |
2163 | // iyi
2164 | if (
2165 | (foo === 123 || bar === 'abc')
2166 | && doesItLookGoodWhenItBecomesThatLong()
2167 | && isThisReallyHappening()
2168 | ) {
2169 | thing1();
2170 | }
2171 |
2172 | // iyi
2173 | if (foo === 123 && bar === 'abc') {
2174 | thing1();
2175 | }
2176 | ```
2177 |
2178 |
2179 | - [17.2](#control-statements--value-selection) Selection operatörülerini kontrol ifadeleri içerisinde kullanmayın.
2180 |
2181 | ```javascript
2182 | // kötü
2183 | !isRunning && startRunning();
2184 |
2185 | // iyi
2186 | if (!isRunning) {
2187 | startRunning();
2188 | }
2189 | ```
2190 |
2191 | **[⬆ başa dön](#İçindekiler)**
2192 |
2193 | ## Yorumlar
2194 |
2195 |
2196 | - [18.1](#comments--multiline) Çok satırlı yorumlarda `/** ... */` kullanın.
2197 |
2198 | ```javascript
2199 | // kötü
2200 | // make() aktarılan tag'a göre
2201 | // yeni bir element return eder
2202 | //
2203 | // @param {String} tag
2204 | // @return {Element} element
2205 | function make(tag) {
2206 |
2207 | // ...
2208 |
2209 | return element;
2210 | }
2211 |
2212 | // iyi
2213 | /**
2214 | * make() aktarılan tag'a göre
2215 | * yeni bir element return eder
2216 | */
2217 | function make(tag) {
2218 |
2219 | // ...
2220 |
2221 | return element;
2222 | }
2223 | ```
2224 |
2225 |
2226 | - [18.2](#comments--singleline) 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.
2227 |
2228 | ```javascript
2229 | // kötü
2230 | const active = true; // aktif bölüm
2231 |
2232 | // iyi
2233 | // is current tab
2234 | const active = true;
2235 |
2236 | // kötü
2237 | function getType() {
2238 | console.log('fetching type...');
2239 | // varsayılanı 'no type' ayarlanır
2240 | const type = this.type || 'no type';
2241 |
2242 | return type;
2243 | }
2244 |
2245 | // iyi
2246 | function getType() {
2247 | console.log('fetching type...');
2248 |
2249 | // varsayılanı 'no type' ayarlanır
2250 | const type = this.type || 'no type';
2251 |
2252 | return type;
2253 | }
2254 |
2255 | // iyi
2256 | function getType() {
2257 | // varsayılanı 'no type' ayarlanır
2258 | const type = this.type || 'no type';
2259 |
2260 | return type;
2261 | }
2262 | ```
2263 |
2264 |
2265 | - [18.3](#comments--spaces) Yorumlardan önce okunabilirliği artırmak için bir boşluk karakteri kullanın. eslint: [`spaced-comment`](https://eslint.org/docs/rules/spaced-comment)
2266 |
2267 | ```javascript
2268 | // kötü
2269 | //aktif bölüm
2270 | const active = true;
2271 |
2272 | // iyi
2273 | // aktif bölüm
2274 | const active = true;
2275 |
2276 | // kötü
2277 | /**
2278 | *make() aktarılan tag'a göre
2279 | *yeni bir element return eder
2280 | */
2281 | function make(tag) {
2282 |
2283 | // ...
2284 |
2285 | return element;
2286 | }
2287 |
2288 | // iyi
2289 | /**
2290 | * make() aktarılan tag'a göre
2291 | * yeni bir element return eder
2292 | */
2293 | function make(tag) {
2294 |
2295 | // ...
2296 |
2297 | return element;
2298 | }
2299 | ```
2300 |
2301 |
2302 | - [18.4](#comments--actionitems) `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`.
2303 |
2304 |
2305 | - [18.5](#comments--fixme) Sorunlara dikkat çekmek için `// FIXME:` kullanın.
2306 |
2307 | ```javascript
2308 | class Calculator extends Abacus {
2309 | constructor() {
2310 | super();
2311 |
2312 | // FIXME: burada global kullanılmamalı
2313 | total = 0;
2314 | }
2315 | }
2316 | ```
2317 |
2318 |
2319 | - [18.6](#comments--todo) Sorunlara çözüm önermek için `// TODO:` kullanın.
2320 |
2321 | ```javascript
2322 | class Calculator extends Abacus {
2323 | constructor() {
2324 | super();
2325 |
2326 | // TODO: total, options parametresi ile ayarlanabilmeli
2327 | this.total = 0;
2328 | }
2329 | }
2330 | ```
2331 |
2332 | **[⬆ başa dön](#İçindekiler)**
2333 |
2334 | ## Whitespace
2335 |
2336 |
2337 | - [19.1](#whitespace--spaces) Soft tab'ı(boşluk karakteri) 2 boşluğa ayarlayın. eslint: [`indent`](https://eslint.org/docs/rules/indent.html) jscs: [`validateIndentation`](http://jscs.info/rule/validateIndentation)
2338 |
2339 | ```javascript
2340 | // kötü
2341 | function foo() {
2342 | ∙∙∙∙let name;
2343 | }
2344 |
2345 | // kötü
2346 | function bar() {
2347 | ∙let name;
2348 | }
2349 |
2350 | // iyi
2351 | function baz() {
2352 | ∙∙let name;
2353 | }
2354 | ```
2355 |
2356 |
2357 | - [19.2](#whitespace--before-blocks) Bloğu kapsayan süslü parantezini açmadan önce bir adet boşluk karakteri kullanın. eslint: [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks.html) jscs: [`requireSpaceBeforeBlockStatements`](http://jscs.info/rule/requireSpaceBeforeBlockStatements)
2358 |
2359 | ```javascript
2360 | // kötü
2361 | function test(){
2362 | console.log('test');
2363 | }
2364 |
2365 | // iyi
2366 | function test() {
2367 | console.log('test');
2368 | }
2369 |
2370 | // kötü
2371 | dog.set('attr',{
2372 | age: '1 year',
2373 | breed: 'Bernese Mountain Dog',
2374 | });
2375 |
2376 | // iyi
2377 | dog.set('attr', {
2378 | age: '1 year',
2379 | breed: 'Bernese Mountain Dog',
2380 | });
2381 | ```
2382 |
2383 |
2384 | - [19.3](#whitespace--around-keywords) 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`](https://eslint.org/docs/rules/keyword-spacing.html) jscs: [`requireSpaceAfterKeywords`](http://jscs.info/rule/requireSpaceAfterKeywords)
2385 |
2386 | ```javascript
2387 | // kötü
2388 | if(isJedi) {
2389 | fight ();
2390 | }
2391 |
2392 | // iyi
2393 | if (isJedi) {
2394 | fight();
2395 | }
2396 |
2397 | // kötü
2398 | function fight () {
2399 | console.log ('Swooosh!');
2400 | }
2401 |
2402 | // iyi
2403 | function fight() {
2404 | console.log('Swooosh!');
2405 | }
2406 | ```
2407 |
2408 |
2409 | - [19.4](#whitespace--infix-ops) Operatörleri boşluk karakteri ile ayırın. eslint: [`space-infix-ops`](https://eslint.org/docs/rules/space-infix-ops.html) jscs: [`requireSpaceBeforeBinaryOperators`](http://jscs.info/rule/requireSpaceBeforeBinaryOperators), [`requireSpaceAfterBinaryOperators`](http://jscs.info/rule/requireSpaceAfterBinaryOperators)
2410 |
2411 | ```javascript
2412 | // kötü
2413 | const x=y+5;
2414 |
2415 | // iyi
2416 | const x = y + 5;
2417 | ```
2418 |
2419 |
2420 | - [19.5](#whitespace--newline-at-end) Dosya sonlarında yeni satır karakterini kullanın. eslint: [`eol-last`](https://github.com/eslint/eslint/blob/master/docs/rules/eol-last.md)
2421 |
2422 | ```javascript
2423 | // kötü
2424 | import { es6 } from './AirbnbStyleGuide';
2425 | // ...
2426 | export default es6;
2427 | ```
2428 |
2429 | ```javascript
2430 | // kötü
2431 | import { es6 } from './AirbnbStyleGuide';
2432 | // ...
2433 | export default es6;↵
2434 | ↵
2435 | ```
2436 |
2437 | ```javascript
2438 | // iyi
2439 | import { es6 } from './AirbnbStyleGuide';
2440 | // ...
2441 | export default es6;↵
2442 | ```
2443 |
2444 |
2445 | - [19.6](#whitespace--chains) 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`](https://eslint.org/docs/rules/newline-per-chained-call) [`no-whitespace-before-property`](https://eslint.org/docs/rules/no-whitespace-before-property)
2446 |
2447 | ```javascript
2448 | // kötü
2449 | $('#items').find('.selected').highlight().end().find('.open').updateCount();
2450 |
2451 | // kötü
2452 | $('#items').
2453 | find('.selected').
2454 | highlight().
2455 | end().
2456 | find('.open').
2457 | updateCount();
2458 |
2459 | // iyi
2460 | $('#items')
2461 | .find('.selected')
2462 | .highlight()
2463 | .end()
2464 | .find('.open')
2465 | .updateCount();
2466 |
2467 | // kötü
2468 | const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true)
2469 | .attr('width', (radius + margin) * 2).append('svg:g')
2470 | .attr('transform', `translate(${radius + margin},${radius + margin})`)
2471 | .call(tron.led);
2472 |
2473 | // iyi
2474 | const leds = stage.selectAll('.led')
2475 | .data(data)
2476 | .enter().append('svg:svg')
2477 | .classed('led', true)
2478 | .attr('width', (radius + margin) * 2)
2479 | .append('svg:g')
2480 | .attr('transform', `translate(${radius + margin},${radius + margin})`)
2481 | .call(tron.led);
2482 |
2483 | // iyi
2484 | const leds = stage.selectAll('.led').data(data);
2485 | ```
2486 |
2487 |
2488 | - [19.7](#whitespace--after-blocks) Bloklardan sonra yeni ifadeye geçmeden önce bir adet boş satır bırakın. jscs: [`requirePaddingNewLinesAfterBlocks`](http://jscs.info/rule/requirePaddingNewLinesAfterBlocks)
2489 |
2490 | ```javascript
2491 | // kötü
2492 | if (foo) {
2493 | return bar;
2494 | }
2495 | return baz;
2496 |
2497 | // iyi
2498 | if (foo) {
2499 | return bar;
2500 | }
2501 |
2502 | return baz;
2503 |
2504 | // kötü
2505 | const obj = {
2506 | foo() {
2507 | },
2508 | bar() {
2509 | },
2510 | };
2511 | return obj;
2512 |
2513 | // iyi
2514 | const obj = {
2515 | foo() {
2516 | },
2517 |
2518 | bar() {
2519 | },
2520 | };
2521 |
2522 | return obj;
2523 |
2524 | // kötü
2525 | const arr = [
2526 | function foo() {
2527 | },
2528 | function bar() {
2529 | },
2530 | ];
2531 | return arr;
2532 |
2533 | // iyi
2534 | const arr = [
2535 | function foo() {
2536 | },
2537 |
2538 | function bar() {
2539 | },
2540 | ];
2541 |
2542 | return arr;
2543 | ```
2544 |
2545 |
2546 | - [19.8](#whitespace--padded-blocks) Blokların içinde boş satırlar bırakmayın. eslint: [`padded-blocks`](https://eslint.org/docs/rules/padded-blocks.html) jscs: [`disallowPaddingNewlinesInBlocks`](http://jscs.info/rule/disallowPaddingNewlinesInBlocks)
2547 |
2548 | ```javascript
2549 | // kötü
2550 | function bar() {
2551 |
2552 | console.log(foo);
2553 |
2554 | }
2555 |
2556 | // kötü
2557 | if (baz) {
2558 |
2559 | console.log(qux);
2560 | } else {
2561 | console.log(foo);
2562 |
2563 | }
2564 |
2565 | // kötü
2566 | class Foo {
2567 |
2568 | constructor(bar) {
2569 | this.bar = bar;
2570 | }
2571 | }
2572 |
2573 | // iyi
2574 | function bar() {
2575 | console.log(foo);
2576 | }
2577 |
2578 | // iyi
2579 | if (baz) {
2580 | console.log(qux);
2581 | } else {
2582 | console.log(foo);
2583 | }
2584 | ```
2585 |
2586 |
2587 | - [19.9](#whitespace--in-parens) Parantez içinde boşluk kullanmayın. eslint: [`space-in-parens`](https://eslint.org/docs/rules/space-in-parens.html) jscs: [`disallowSpacesInsideParentheses`](http://jscs.info/rule/disallowSpacesInsideParentheses)
2588 |
2589 | ```javascript
2590 | // kötü
2591 | function bar( foo ) {
2592 | return foo;
2593 | }
2594 |
2595 | // iyi
2596 | function bar(foo) {
2597 | return foo;
2598 | }
2599 |
2600 | // kötü
2601 | if ( foo ) {
2602 | console.log(foo);
2603 | }
2604 |
2605 | // iyi
2606 | if (foo) {
2607 | console.log(foo);
2608 | }
2609 | ```
2610 |
2611 |
2612 | - [19.10](#whitespace--in-brackets) Köşeli parantez içinde boşluk kullanmayın. eslint: [`array-bracket-spacing`](https://eslint.org/docs/rules/array-bracket-spacing.html) jscs: [`disallowSpacesInsideArrayBrackets`](http://jscs.info/rule/disallowSpacesInsideArrayBrackets)
2613 |
2614 | ```javascript
2615 | // kötü
2616 | const foo = [ 1, 2, 3 ];
2617 | console.log(foo[ 0 ]);
2618 |
2619 | // iyi
2620 | const foo = [1, 2, 3];
2621 | console.log(foo[0]);
2622 | ```
2623 |
2624 |
2625 | - [19.11](#whitespace--in-braces) Süslü parantez içinde boşluk kullanın. eslint: [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing.html) jscs: [`requireSpacesInsideObjectBrackets`](http://jscs.info/rule/requireSpacesInsideObjectBrackets)
2626 |
2627 | ```javascript
2628 | // kötü
2629 | const foo = {clark: 'kent'};
2630 |
2631 | // iyi
2632 | const foo = { clark: 'kent' };
2633 | ```
2634 |
2635 |
2636 | - [19.12](#whitespace--max-len) 100 karakterden uzun satırlar yazmayın. (whitespace dahil). Not: Uzun string'ler [yukarıda](#strings--line-length) belirtildiği gibi bu kuraldan muaftır. eslint: [`max-len`](https://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength)
2637 |
2638 | > Neden? Geliştirilebilirliği ve okunabilirliği artırmaktadır.
2639 |
2640 | ```javascript
2641 | // kötü
2642 | const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;
2643 |
2644 | // kötü
2645 | $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));
2646 |
2647 | // iyi
2648 | const foo = jsonData
2649 | && jsonData.foo
2650 | && jsonData.foo.bar
2651 | && jsonData.foo.bar.baz
2652 | && jsonData.foo.bar.baz.quux
2653 | && jsonData.foo.bar.baz.quux.xyzzy;
2654 |
2655 | // iyi
2656 | $.ajax({
2657 | method: 'POST',
2658 | url: 'https://airbnb.com/',
2659 | data: { name: 'John' },
2660 | })
2661 | .done(() => console.log('Congratulations!'))
2662 | .fail(() => console.log('You have failed this city.'));
2663 | ```
2664 |
2665 | **[⬆ başa dön](#İçindekiler)**
2666 |
2667 | ## Virgüller
2668 |
2669 |
2670 | - [20.1](#commas--leading-trailing) **Asla** virgül ile başlamayın. eslint: [`comma-style`](https://eslint.org/docs/rules/comma-style.html) jscs: [`requireCommaBeforeLineBreak`](http://jscs.info/rule/requireCommaBeforeLineBreak)
2671 |
2672 | ```javascript
2673 | // kötü
2674 | const story = [
2675 | once
2676 | , upon
2677 | , aTime
2678 | ];
2679 |
2680 | // iyi
2681 | const story = [
2682 | once,
2683 | upon,
2684 | aTime,
2685 | ];
2686 |
2687 | // kötü
2688 | const hero = {
2689 | firstName: 'Ada'
2690 | , lastName: 'Lovelace'
2691 | , birthYear: 1815
2692 | , superPower: 'computers'
2693 | };
2694 |
2695 | // iyi
2696 | const hero = {
2697 | firstName: 'Ada',
2698 | lastName: 'Lovelace',
2699 | birthYear: 1815,
2700 | superPower: 'computers',
2701 | };
2702 | ```
2703 |
2704 |
2705 | - [20.2](#commas--dangling) Liste sonlarında da kullanın. eslint: [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle.html) jscs: [`requireTrailingComma`](http://jscs.info/rule/requireTrailingComma)
2706 |
2707 | > 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](https://github.com/airbnb/javascript/blob/es5-deprecated/es5/README.md#commas)'nu düşünmenize gerek kalmayacaktır.
2708 |
2709 | ```diff
2710 | // kötü - sonda virgül olmadığında git diff
2711 | const hero = {
2712 | firstName: 'Florence',
2713 | - lastName: 'Nightingale'
2714 | + lastName: 'Nightingale',
2715 | + inventorOf: ['coxcomb chart', 'modern nursing']
2716 | };
2717 |
2718 | // iyi - sonda virgül olduğunda git diff
2719 | const hero = {
2720 | firstName: 'Florence',
2721 | lastName: 'Nightingale',
2722 | + inventorOf: ['coxcomb chart', 'modern nursing'],
2723 | };
2724 | ```
2725 |
2726 | ```javascript
2727 | // kötü
2728 | const hero = {
2729 | firstName: 'Dana',
2730 | lastName: 'Scully'
2731 | };
2732 |
2733 | const heroes = [
2734 | 'Batman',
2735 | 'Superman'
2736 | ];
2737 |
2738 | // iyi
2739 | const hero = {
2740 | firstName: 'Dana',
2741 | lastName: 'Scully',
2742 | };
2743 |
2744 | const heroes = [
2745 | 'Batman',
2746 | 'Superman',
2747 | ];
2748 |
2749 | // kötü
2750 | function createHero(
2751 | firstName,
2752 | lastName,
2753 | inventorOf
2754 | ) {
2755 | // does nothing
2756 | }
2757 |
2758 | // iyi
2759 | function createHero(
2760 | firstName,
2761 | lastName,
2762 | inventorOf,
2763 | ) {
2764 | // does nothing
2765 | }
2766 |
2767 | // iyi (unutmayın rest elemanından sonra virgül kullanılmamalıdır)
2768 | function createHero(
2769 | firstName,
2770 | lastName,
2771 | inventorOf,
2772 | ...heroArgs
2773 | ) {
2774 | // does nothing
2775 | }
2776 |
2777 | // kötü
2778 | createHero(
2779 | firstName,
2780 | lastName,
2781 | inventorOf
2782 | );
2783 |
2784 | // good
2785 | createHero(
2786 | firstName,
2787 | lastName,
2788 | inventorOf,
2789 | );
2790 |
2791 | // iyi (unutmayın rest elemanından sonra virgül kullanılmamalıdır)
2792 | createHero(
2793 | firstName,
2794 | lastName,
2795 | inventorOf,
2796 | ...heroArgs
2797 | );
2798 | ```
2799 |
2800 | **[⬆ başa dön](#İçindekiler)**
2801 |
2802 | ## Noktalı Virgüller
2803 |
2804 |
2805 | - [21.1](#semicolons--required) Noktalı virgül kullanımına dikkat edilmelidir. eslint: [`semi`](https://eslint.org/docs/rules/semi.html) jscs: [`requireSemicolons`](http://jscs.info/rule/requireSemicolons)
2806 |
2807 | > Neden? Javascript yorumlayıcıları noktalı virgül olmadan yeni satıra geçilen bölümleri [Otomatik Noktalı Virgül Ekleme](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) 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.
2808 |
2809 | ```javascript
2810 | // kötü - hata verir
2811 | const luke = {}
2812 | const leia = {}
2813 | [luke, leia].forEach(jedi => jedi.father = 'vader')
2814 |
2815 | // kötü - hata verir
2816 | const reaction = "No! That's impossible!"
2817 | (async function meanwhileOnTheFalcon() {
2818 | // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
2819 | // ...
2820 | }())
2821 |
2822 | // 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!
2823 | function foo() {
2824 | return
2825 | 'search your feelings, you know it to be foo'
2826 | }
2827 |
2828 | // iyi
2829 | const luke = {};
2830 | const leia = {};
2831 | [luke, leia].forEach((jedi) => {
2832 | jedi.father = 'vader';
2833 | });
2834 |
2835 | // iyi
2836 | const reaction = "No! That's impossible!";
2837 | (async function meanwhileOnTheFalcon() {
2838 | // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
2839 | // ...
2840 | }());
2841 |
2842 | // iyi
2843 | function foo() {
2844 | return 'search your feelings, you know it to be foo';
2845 | }
2846 | ```
2847 |
2848 | [Daha fazla](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214#7365214).
2849 |
2850 | **[⬆ başa dön](#İçindekiler)**
2851 |
2852 | ## Tip Dönüştürme
2853 |
2854 |
2855 | - [22.1](#coercion--explicit) Dönüştürme işlemlerini ifadelerin en başında uygulayın.
2856 |
2857 |
2858 | - [22.2](#coercion--strings) String için; eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
2859 |
2860 | ```javascript
2861 | // => this.reviewScore = 9;
2862 |
2863 | // kötü
2864 | const totalScore = new String(this.reviewScore); // totalScore'un typeof değeri "object"'dir. "string" değil.
2865 |
2866 | // kötü
2867 | const totalScore = this.reviewScore + ''; // this.reviewScore.valueOf()'u uygular
2868 |
2869 | // kötü
2870 | const totalScore = this.reviewScore.toString(); // string döneceğini garanti etmez
2871 |
2872 | // iyi
2873 | const totalScore = String(this.reviewScore);
2874 | ```
2875 |
2876 |
2877 | - [22.3](#coercion--numbers) 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`](https://eslint.org/docs/rules/radix) [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
2878 |
2879 | ```javascript
2880 | const inputValue = '4';
2881 |
2882 | // kötü
2883 | const val = new Number(inputValue);
2884 |
2885 | // kötü
2886 | const val = +inputValue;
2887 |
2888 | // kötü
2889 | const val = inputValue >> 0;
2890 |
2891 | // kötü
2892 | const val = parseInt(inputValue);
2893 |
2894 | // iyi
2895 | const val = Number(inputValue);
2896 |
2897 | // iyi
2898 | const val = parseInt(inputValue, 10);
2899 | ```
2900 |
2901 |
2902 | - [22.4](#coercion--comment-deviations) Herhangi bir sebeple `parseInt` yerine [performas sebebiyle](https://jsperf.com/coercion-vs-casting/3) Bitshift yapıyorsanız, nedenine ilişkin bir yorum bırakın.
2903 |
2904 | ```javascript
2905 | // iyi
2906 | /**
2907 | * parseInt yüzünden kodum yavaş çalışıyordu
2908 | * Bitshifting String'i Number'a
2909 | * daha hızlı çeviriyor
2910 | */
2911 | const val = inputValue >> 0;
2912 | ```
2913 |
2914 |
2915 | - [22.5](#coercion--bitwise) **Not:** Bitshift işlemlerinde dikkatli olun. Number'lar [64-bit değeriyle](https://es5.github.io/#x4.3.19) sunulur fakat bitshift işlemleri daima 32-bit integer ([source](https://es5.github.io/#x11.7)) döner. Bitshift işlemleri 32 bit'den büyük integer değerlerde beklenmeyen davranışlara neden olabilir. [Tartışma](https://github.com/airbnb/javascript/issues/109). En büyük 32-bit Int 2,147,483,647:
2916 |
2917 | ```javascript
2918 | 2147483647 >> 0; // => 2147483647
2919 | 2147483648 >> 0; // => -2147483648
2920 | 2147483649 >> 0; // => -2147483647
2921 | ```
2922 |
2923 |
2924 | - [22.6](#coercion--booleans) Boolean için; eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
2925 |
2926 | ```javascript
2927 | const age = 0;
2928 |
2929 | // kötü
2930 | const hasAge = new Boolean(age);
2931 |
2932 | // iyi
2933 | const hasAge = Boolean(age);
2934 |
2935 | // çok iyi
2936 | const hasAge = !!age;
2937 | ```
2938 |
2939 | **[⬆ başa dön](#İçindekiler)**
2940 |
2941 | ## İsimlendirme
2942 |
2943 |
2944 | - [23.1](#naming--descriptive) Tek harfli isimlendirmelerden kaçının. İsimlerde açıklayıcı olun. eslint: [`id-length`](https://eslint.org/docs/rules/id-length)
2945 |
2946 | ```javascript
2947 | // kötü
2948 | function q() {
2949 | // ...
2950 | }
2951 |
2952 | // iyi
2953 | function query() {
2954 | // ...
2955 | }
2956 | ```
2957 |
2958 |
2959 | - [23.2](#naming--camelCase) Nesne, fonksiyon, ve instance'larda camelCase isimlendirme yapın. eslint: [`camelcase`](https://eslint.org/docs/rules/camelcase.html) jscs: [`requireCamelCaseOrUpperCaseIdentifiers`](http://jscs.info/rule/requireCamelCaseOrUpperCaseIdentifiers)
2960 |
2961 | ```javascript
2962 | // kötü
2963 | const OBJEcttsssss = {};
2964 | const this_is_my_object = {};
2965 | function c() {}
2966 |
2967 | // iyi
2968 | const thisIsMyObject = {};
2969 | function thisIsMyFunction() {}
2970 | ```
2971 |
2972 |
2973 | - [23.3](#naming--PascalCase) Sınıf ve constructor'larda pascalCase kullanın. eslint: [`new-cap`](https://eslint.org/docs/rules/new-cap.html) jscs: [`requireCapitalizedConstructors`](http://jscs.info/rule/requireCapitalizedConstructors)
2974 |
2975 | ```javascript
2976 | // kötü
2977 | function user(options) {
2978 | this.name = options.name;
2979 | }
2980 |
2981 | const bad = new user({
2982 | name: 'nope',
2983 | });
2984 |
2985 | // iyi
2986 | class User {
2987 | constructor(options) {
2988 | this.name = options.name;
2989 | }
2990 | }
2991 |
2992 | const good = new User({
2993 | name: 'yup',
2994 | });
2995 | ```
2996 |
2997 |
2998 | - [23.4](#naming--leading-underscore) Sonlarda ve başlarda alt çizgi kullanmayın. eslint: [`no-underscore-dangle`](https://eslint.org/docs/rules/no-underscore-dangle.html) jscs: [`disallowDanglingUnderscores`](http://jscs.info/rule/disallowDanglingUnderscores)
2999 |
3000 | > 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.
3001 |
3002 | ```javascript
3003 | // kötü
3004 | this.__firstName__ = 'Panda';
3005 | this.firstName_ = 'Panda';
3006 | this._firstName = 'Panda';
3007 |
3008 | // iyi
3009 | this.firstName = 'Panda';
3010 |
3011 | // iyi
3012 | // see https://kangax.github.io/compat-table/es6/#test-WeakMap
3013 | const firstNames = new WeakMap();
3014 | firstNames.set(this, 'Panda');
3015 | ```
3016 |
3017 |
3018 | - [23.5](#naming--self-this) Referansları `this` ile aktarmayın. Arrow fonksiyonları ya da [Function#bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) kullanın. jscs: [`disallowNodeTypes`](http://jscs.info/rule/disallowNodeTypes)
3019 |
3020 | ```javascript
3021 | // kötü
3022 | function foo() {
3023 | const self = this;
3024 | return function () {
3025 | console.log(self);
3026 | };
3027 | }
3028 |
3029 | // kötü
3030 | function foo() {
3031 | const that = this;
3032 | return function () {
3033 | console.log(that);
3034 | };
3035 | }
3036 |
3037 | // iyi
3038 | function foo() {
3039 | return () => {
3040 | console.log(this);
3041 | };
3042 | }
3043 | ```
3044 |
3045 |
3046 | - [23.6](#naming--filename-matches-export) Ana dosya adı default export adı ile birebir uyuşmalıdır.
3047 |
3048 | ```javascript
3049 | // file 1 contents
3050 | class CheckBox {
3051 | // ...
3052 | }
3053 | export default CheckBox;
3054 |
3055 | // file 2 contents
3056 | export default function fortyTwo() { return 42; }
3057 |
3058 | // file 3 contents
3059 | export default function insideDirectory() {}
3060 |
3061 | // in some other file
3062 | // kötü
3063 | import CheckBox from './checkBox'; // PascalCase import/export, camelCase dosya adı
3064 | import FortyTwo from './FortyTwo'; // PascalCase import/dosya adı, camelCase export
3065 | import InsideDirectory from './InsideDirectory'; // PascalCase import/dosya adı, camelCase export
3066 |
3067 | // kötü
3068 | import CheckBox from './check_box'; // PascalCase import/export, snake_case dosya adı
3069 | import forty_two from './forty_two'; // snake_case import/dosya adı, camelCase export
3070 | import inside_directory from './inside_directory'; // snake_case import, camelCase export
3071 | import index from './inside_directory/index'; // index dosyasını zorunlu kılar
3072 | import insideDirectory from './insideDirectory/index'; // index dosyasını zorunlu kılar
3073 |
3074 | // iyi
3075 | import CheckBox from './CheckBox'; // PascalCase export/import/dosya adı
3076 | import fortyTwo from './fortyTwo'; // camelCase export/import/dosya adı
3077 | import insideDirectory from './insideDirectory'; // camelCase export/import/klasör name/implicit "index"
3078 | // ^ hem insideDirectory.js hem de insideDirectory/index.js için geçerlidir
3079 | ```
3080 |
3081 |
3082 | - [23.7](#naming--camelCase-default-export) Default export fonksiyonlarında camelCase kullanın. Dosya adınız fonksiyon adı ile aynı olmalıdır.
3083 |
3084 | ```javascript
3085 | function makeStyleGuide() {
3086 | // ...
3087 | }
3088 |
3089 | export default makeStyleGuide;
3090 | ```
3091 |
3092 |
3093 | - [23.8](#naming--PascalCase-singleton) Constructor / class / singleton / function library / bare object; export ederken PascalCase kullanın.
3094 |
3095 | ```javascript
3096 | const AirbnbStyleGuide = {
3097 | es6: {
3098 | },
3099 | };
3100 |
3101 | export default AirbnbStyleGuide;
3102 | ```
3103 |
3104 |
3105 | - [23.9](#naming--Acronyms-and-Initialisms) Kısaltma isimlerin tümü büyük harfle ya da küçük harfle yazılmalıdır.
3106 |
3107 | > Neden? İsimler bilgisayar algoritması değildir ve okunabilirliğe göre seçilmelidir.
3108 |
3109 | ```javascript
3110 | // kötü
3111 | import SmsContainer from './containers/SmsContainer';
3112 |
3113 | // kötü
3114 | const HttpRequests = [
3115 | // ...
3116 | ];
3117 |
3118 | // iyi
3119 | import SMSContainer from './containers/SMSContainer';
3120 |
3121 | // iyi
3122 | const HTTPRequests = [
3123 | // ...
3124 | ];
3125 |
3126 | // iyi
3127 | const httpRequests = [
3128 | // ...
3129 | ];
3130 |
3131 | // çok iyi
3132 | import TextMessageContainer from './containers/TextMessageContainer';
3133 |
3134 | // çok iyi
3135 | const requests = [
3136 | // ...
3137 | ];
3138 | ```
3139 |
3140 | **[⬆ başa dön](#İçindekiler)**
3141 |
3142 | ## Accessor
3143 |
3144 |
3145 | - [24.1](#accessors--not-required) Propertylerde accessor fonksiyon kullanımı gerekli değildir.
3146 |
3147 |
3148 | - [24.2](#accessors--no-getters-setters) 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.
3149 |
3150 | ```javascript
3151 | // kötü
3152 | class Dragon {
3153 | get age() {
3154 | // ...
3155 | }
3156 |
3157 | set age(value) {
3158 | // ...
3159 | }
3160 | }
3161 |
3162 | // iyi
3163 | class Dragon {
3164 | getAge() {
3165 | // ...
3166 | }
3167 |
3168 | setAge(value) {
3169 | // ...
3170 | }
3171 | }
3172 | ```
3173 |
3174 |
3175 | - [24.3](#accessors--boolean-prefix) Eğer property/metod `boolean` ise, `isVal()` veya `hasVal()` kullanın.
3176 |
3177 | ```javascript
3178 | // kötü
3179 | if (!dragon.age()) {
3180 | return false;
3181 | }
3182 |
3183 | // iyi
3184 | if (!dragon.hasAge()) {
3185 | return false;
3186 | }
3187 | ```
3188 |
3189 |
3190 | - [24.4](#accessors--consistent) get() ve set() fonksiyonları oluşturabilirsiniz fakat daima tutarlı olun.
3191 |
3192 | ```javascript
3193 | class Jedi {
3194 | constructor(options = {}) {
3195 | const lightsaber = options.lightsaber || 'blue';
3196 | this.set('lightsaber', lightsaber);
3197 | }
3198 |
3199 | set(key, val) {
3200 | this[key] = val;
3201 | }
3202 |
3203 | get(key) {
3204 | return this[key];
3205 | }
3206 | }
3207 | ```
3208 |
3209 | **[⬆ başa dön](#İçindekiler)**
3210 |
3211 | ## Olaylar
3212 |
3213 |
3214 | - [25.1](#events--hash) 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.
3215 |
3216 | ```javascript
3217 | // kötü
3218 | $(this).trigger('listingUpdated', listing.id);
3219 |
3220 | // ...
3221 |
3222 | $(this).on('listingUpdated', (e, listingID) => {
3223 | // do something with listingID
3224 | });
3225 | ```
3226 |
3227 | ```javascript
3228 | // iyi
3229 | $(this).trigger('listingUpdated', { listingID: listing.id });
3230 |
3231 | // ...
3232 |
3233 | $(this).on('listingUpdated', (e, data) => {
3234 | // do something with data.listingID
3235 | });
3236 | ```
3237 |
3238 | **[⬆ başa dön](#İçindekiler)**
3239 |
3240 | ## jQuery
3241 |
3242 |
3243 | - [26.1](#jquery--dollar-prefix) jQuery değişkenlerinde `$` öneki kullanın. jscs: [`requireDollarBeforejQueryAssignment`](http://jscs.info/rule/requireDollarBeforejQueryAssignment)
3244 |
3245 | ```javascript
3246 | // kötü
3247 | const sidebar = $('.sidebar');
3248 |
3249 | // iyi
3250 | const $sidebar = $('.sidebar');
3251 |
3252 | // iyi
3253 | const $sidebarBtn = $('.sidebar-btn');
3254 | ```
3255 |
3256 |
3257 | - [26.2](#jquery--cache) jQuery lookup'larını önbelleğe alın.
3258 |
3259 | ```javascript
3260 | // kötü
3261 | function setSidebar() {
3262 | $('.sidebar').hide();
3263 |
3264 | // ...
3265 |
3266 | $('.sidebar').css({
3267 | 'background-color': 'pink',
3268 | });
3269 | }
3270 |
3271 | // iyi
3272 | function setSidebar() {
3273 | const $sidebar = $('.sidebar');
3274 | $sidebar.hide();
3275 |
3276 | // ...
3277 |
3278 | $sidebar.css({
3279 | 'background-color': 'pink',
3280 | });
3281 | }
3282 | ```
3283 |
3284 |
3285 | - [26.3](#jquery--queries) DOM query'lerde cascading `$('.sidebar ul')` ya da parent > child `$('.sidebar > ul')` yöntemini kullanın. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
3286 |
3287 |
3288 | - [26.4](#jquery--find) Scope içerisinde çalışan jQuery sorgularında `find` kullanın.
3289 |
3290 | ```javascript
3291 | // kötü
3292 | $('ul', '.sidebar').hide();
3293 |
3294 | // kötü
3295 | $('.sidebar').find('ul').hide();
3296 |
3297 | // iyi
3298 | $('.sidebar ul').hide();
3299 |
3300 | // iyi
3301 | $('.sidebar > ul').hide();
3302 |
3303 | // iyi
3304 | $sidebar.find('ul').hide();
3305 | ```
3306 |
3307 | **[⬆ başa dön](#İçindekiler)**
3308 |
3309 | ## ECMAScript 5 Uyumluluğu
3310 |
3311 |
3312 | - [27.1](#es5-compat--kangax) [Kangax](https://twitter.com/kangax/)'ın ES5 [uyumluluk tablosu](https://kangax.github.io/es5-compat-table/)'nu inceleyin.
3313 |
3314 | **[⬆ başa dön](#İçindekiler)**
3315 |
3316 |
3317 | ## ECMAScript 6+ (ES 2015+) Özellikleri
3318 |
3319 |
3320 | - [28.1](#es6-styles) Aşağıda çeşitli ES6+ özelliklerinin bir listesini bulabilirsiniz.
3321 |
3322 | 1. [Arrow Fonksiyonlar](#arrow-functions)
3323 | 1. [Sınıflar](#classes--constructors)
3324 | 1. [Nesnelerde Shorthand](#es6-object-shorthand)
3325 | 1. [Nesnelerde Concise](#es6-object-concise)
3326 | 1. [Dinamik Şekilde Oluşturulan Nesne Property'leri](#es6-computed-properties)
3327 | 1. [String Şablonları](#es6-template-literals)
3328 | 1. [Destructuring](#destructuring)
3329 | 1. [Varsayılan Parametreler](#es6-default-parameters)
3330 | 1. [Rest](#es6-rest)
3331 | 1. [Dizilerde Spread](#es6-array-spreads)
3332 | 1. [Let ve Const](#references)
3333 | 1. [Üsalma operatörü](#es2016-properties--exponentiation-operator)
3334 | 1. [Yineleyiciler ve Oluşturucular](#iterators-and-generators)
3335 | 1. [Modüller](#modules)
3336 |
3337 |
3338 | - [28.2](#tc39-proposals) 3. aşamaya ulaşmamış [TC39 önerileri](https://github.com/tc39/proposals)'ni kullanmayın.
3339 |
3340 | > Neden? [Henüz tamamlanmadı](https://tc39.github.io/process-document/) ve halen baştan aşağı değiştirilebilir.
3341 |
3342 | **[⬆ başa dön](#İçindekiler)**
3343 |
3344 | ## Yerleşik Kütüphaneler
3345 |
3346 | [Yerleşik Kütüphaneler](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects)
3347 | fonksiyonel açıdan hatalı olsada legacy sebebiyle varlığını koruyan araçlar içerir.
3348 |
3349 |
3350 | - [29.1](#standard-library--isnan) Global `isNaN` yerine `Number.isNaN` kullanın.
3351 | eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
3352 |
3353 | > Neden? Global `isNaN` sayı-olmayan değerlerde de true döndürebilir.
3354 | > Eğer bu davranışı görmezden gelecekseniz bunu belli edin.
3355 |
3356 | ```javascript
3357 | // kötü
3358 | isNaN('1.2'); // false
3359 | isNaN('1.2.3'); // true
3360 |
3361 | // iyi
3362 | Number.isNaN('1.2.3'); // false
3363 | Number.isNaN(Number('1.2.3')); // true
3364 | ```
3365 |
3366 |
3367 | - [29.2](#standard-library--isfinite) Global `isFinite` yerine `Number.isFinite` kullanın.
3368 | eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
3369 |
3370 | > Neden? Global `isFinite` sayı-olmayan değerlerde de true döndürebilir.
3371 | > Eğer bu davranışı görmezden gelecekseniz bunu belli edin.
3372 |
3373 | ```javascript
3374 | // kötü
3375 | isFinite('2e3'); // true
3376 |
3377 | // iyi
3378 | Number.isFinite('2e3'); // false
3379 | Number.isFinite(parseInt('2e3', 10)); // true
3380 | ```
3381 |
3382 | **[⬆ başa dön](#İçindekiler)**
3383 |
3384 | ## Test
3385 |
3386 |
3387 | - [30.1](#testing--yup) **Daima** test yazılmalıdır.
3388 |
3389 | ```javascript
3390 | function foo() {
3391 | return true;
3392 | }
3393 | ```
3394 |
3395 |
3396 | - [30.2](#testing--for-real) **Dikkat** edeceğiniz bazı kurallar:
3397 | - Hangi test framework'ünü kullanırsanız kullanın mutlaka test yazın!
3398 | - Sade ve kısa fonksiyonlar ile mutasyonları minimize edin.
3399 | - Stub ve mock'lara karşı dikkatli olun - testlerinizi kırılgan hale getirebilirler.
3400 | - Airbnb'de genel de [`mocha`](https://www.npmjs.com/package/mocha) kullanıyoruz. Zaman zaman küçük ve harici modüllerde [`tape`](https://www.npmjs.com/package/tape) de kullanıyoruz.
3401 | - Pratikte ulaşması güç olsada test kapsamında (test coverage) %100, iyi bir hedeftir.
3402 | - 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.
3403 |
3404 | **[⬆ başa dön](#İçindekiler)**
3405 |
3406 | ## Performans
3407 |
3408 | - [On Layout & Web Performance](https://www.kellegous.com/j/2013/01/26/layout-performance/)
3409 | - [String vs Array Concat](https://jsperf.com/string-vs-array-concat/2)
3410 | - [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost)
3411 | - [Bang Function](https://jsperf.com/bang-function)
3412 | - [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/13)
3413 | - [innerHTML vs textContent for script text](https://jsperf.com/innerhtml-vs-textcontent-for-script-text)
3414 | - [Long String Concatenation](https://jsperf.com/ya-string-concat)
3415 | - [Are Javascript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
3416 | - Loading...
3417 |
3418 | **[⬆ başa dön](#İçindekiler)**
3419 |
3420 | ## Kaynaklar
3421 |
3422 | **ES6+ Öğrenin**
3423 |
3424 | - [Latest ECMA spec](https://tc39.github.io/ecma262/)
3425 | - [ExploringJS](http://exploringjs.com/)
3426 | - [ES6 Compatibility Table](https://kangax.github.io/compat-table/es6/)
3427 | - [Comprehensive Overview of ES6 Features](http://es6-features.org/)
3428 |
3429 | **Okuyun**
3430 |
3431 | - [Standard ECMA-262](http://www.ecma-international.org/ecma-262/6.0/index.html)
3432 |
3433 | **Araçlar**
3434 |
3435 | - Code Style Linters
3436 | - [ESlint](https://eslint.org/) - [Airbnb Style .eslintrc](https://github.com/airbnb/javascript/blob/master/linters/.eslintrc)
3437 | - [JSHint](http://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
3438 | - [JSCS](https://github.com/jscs-dev/node-jscs) - [Airbnb Style Preset](https://github.com/jscs-dev/node-jscs/blob/master/presets/airbnb.json) (Deprecated, please use [ESlint](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base))
3439 | - Neutrino preset - [neutrino-preset-airbnb-base](https://neutrino.js.org/presets/neutrino-preset-airbnb-base/)
3440 |
3441 | **Diğer Stil Kılavuzları**
3442 |
3443 | - [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
3444 | - [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/)
3445 | - [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js)
3446 |
3447 | **Diğer Stiller**
3448 |
3449 | - [Naming this in nested functions](https://gist.github.com/cjohansen/4135065) - Christian Johansen
3450 | - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen
3451 | - [Popular JavaScript Coding Conventions on GitHub](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
3452 | - [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
3453 |
3454 | **İlave Okumalar**
3455 |
3456 | - [Understanding JavaScript Closures](https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
3457 | - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
3458 | - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
3459 | - [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
3460 | - [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock
3461 |
3462 | **Kitaplar**
3463 |
3464 | - [JavaScript: The Good Parts](https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
3465 | - [JavaScript Patterns](https://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
3466 | - [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
3467 | - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
3468 | - [Maintainable JavaScript](https://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
3469 | - [JavaScript Web Applications](https://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
3470 | - [Pro JavaScript Techniques](https://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
3471 | - [Smashing Node.js: JavaScript Everywhere](https://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
3472 | - [Secrets of the JavaScript Ninja](https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
3473 | - [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
3474 | - [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
3475 | - [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon
3476 | - [Third Party JavaScript](https://www.manning.com/books/third-party-javascript) - Ben Vinegar and Anton Kovalyov
3477 | - [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman
3478 | - [Eloquent JavaScript](http://eloquentjavascript.net/) - Marijn Haverbeke
3479 | - [You Don’t Know JS: ES6 & Beyond](http://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
3480 |
3481 | **Bloglar**
3482 |
3483 | - [JavaScript Weekly](http://javascriptweekly.com/)
3484 | - [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/)
3485 | - [Bocoup Weblog](https://bocoup.com/weblog)
3486 | - [Adequately Good](http://www.adequatelygood.com/)
3487 | - [NCZOnline](https://www.nczonline.net/)
3488 | - [Perfection Kills](http://perfectionkills.com/)
3489 | - [Ben Alman](http://benalman.com/)
3490 | - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
3491 | - [nettuts](http://code.tutsplus.com/?s=javascript)
3492 |
3493 | **Podcastler**
3494 |
3495 | - [JavaScript Air](https://javascriptair.com/)
3496 | - [JavaScript Jabber](https://devchat.tv/js-jabber/)
3497 |
3498 | **[⬆ başa dön](#İçindekiler)**
3499 |
3500 | ## Organizasyonlar
3501 |
3502 | Kılavuzumuzu kullanan organizasyonların listesi. Pull request göndererek eklemelerde bulunabilirsiniz.
3503 |
3504 | - **123erfasst**: [123erfasst/javascript](https://github.com/123erfasst/javascript)
3505 | - **3blades**: [3Blades](https://github.com/3blades)
3506 | - **4Catalyzer**: [4Catalyzer/javascript](https://github.com/4Catalyzer/javascript)
3507 | - **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript)
3508 | - **Adult Swim**: [adult-swim/javascript](https://github.com/adult-swim/javascript)
3509 | - **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript)
3510 | - **AltSchool**: [AltSchool/javascript](https://github.com/AltSchool/javascript)
3511 | - **Apartmint**: [apartmint/javascript](https://github.com/apartmint/javascript)
3512 | - **Ascribe**: [ascribe/javascript](https://github.com/ascribe/javascript)
3513 | - **Avalara**: [avalara/javascript](https://github.com/avalara/javascript)
3514 | - **Avant**: [avantcredit/javascript](https://github.com/avantcredit/javascript)
3515 | - **Axept**: [axept/javascript](https://github.com/axept/javascript)
3516 | - **BashPros**: [BashPros/javascript](https://github.com/BashPros/javascript)
3517 | - **Billabong**: [billabong/javascript](https://github.com/billabong/javascript)
3518 | - **Bisk**: [bisk](https://github.com/Bisk/)
3519 | - **Bonhomme**: [bonhommeparis/javascript](https://github.com/bonhommeparis/javascript)
3520 | - **Brainshark**: [brainshark/javascript](https://github.com/brainshark/javascript)
3521 | - **CaseNine**: [CaseNine/javascript](https://github.com/CaseNine/javascript)
3522 | - **Chartboost**: [ChartBoost/javascript-style-guide](https://github.com/ChartBoost/javascript-style-guide)
3523 | - **ComparaOnline**: [comparaonline/javascript](https://github.com/comparaonline/javascript-style-guide)
3524 | - **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide)
3525 | - **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript)
3526 | - **DoSomething**: [DoSomething/eslint-config](https://github.com/DoSomething/eslint-config)
3527 | - **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript)
3528 | - **Ecosia**: [ecosia/javascript](https://github.com/ecosia/javascript)
3529 | - **Evernote**: [evernote/javascript-style-guide](https://github.com/evernote/javascript-style-guide)
3530 | - **Evolution Gaming**: [evolution-gaming/javascript](https://github.com/evolution-gaming/javascript)
3531 | - **EvozonJs**: [evozonjs/javascript](https://github.com/evozonjs/javascript)
3532 | - **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript)
3533 | - **Expensify** [Expensify/Style-Guide](https://github.com/Expensify/Style-Guide/blob/master/javascript.md)
3534 | - **Flexberry**: [Flexberry/javascript-style-guide](https://github.com/Flexberry/javascript-style-guide)
3535 | - **Gawker Media**: [gawkermedia](https://github.com/gawkermedia/)
3536 | - **General Electric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript)
3537 | - **Generation Tux**: [GenerationTux/javascript](https://github.com/generationtux/styleguide)
3538 | - **GoodData**: [gooddata/gdc-js-style](https://github.com/gooddata/gdc-js-style)
3539 | - **GreenChef**: [greenchef/javascript](https://github.com/greenchef/javascript)
3540 | - **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript)
3541 | - **Grupo-Abraxas**: [Grupo-Abraxas/javascript](https://github.com/Grupo-Abraxas/javascript)
3542 | - **Honey**: [honeyscience/javascript](https://github.com/honeyscience/javascript)
3543 | - **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript-style-guide)
3544 | - **Huballin**: [huballin](https://github.com/huballin/)
3545 | - **HubSpot**: [HubSpot/javascript](https://github.com/HubSpot/javascript)
3546 | - **Hyper**: [hyperoslo/javascript-playbook](https://github.com/hyperoslo/javascript-playbook/blob/master/style.md)
3547 | - **InterCity Group**: [intercitygroup/javascript-style-guide](https://github.com/intercitygroup/javascript-style-guide)
3548 | - **Jam3**: [Jam3/Javascript-Code-Conventions](https://github.com/Jam3/Javascript-Code-Conventions)
3549 | - **JeopardyBot**: [kesne/jeopardy-bot](https://github.com/kesne/jeopardy-bot/blob/master/STYLEGUIDE.md)
3550 | - **JSSolutions**: [JSSolutions/javascript](https://github.com/JSSolutions/javascript)
3551 | - **Kaplan Komputing**: [kaplankomputing/javascript](https://github.com/kaplankomputing/javascript)
3552 | - **KickorStick**: [kickorstick](https://github.com/kickorstick/)
3553 | - **Kinetica Solutions**: [kinetica/javascript](https://github.com/kinetica/Javascript-style-guide)
3554 | - **LEINWAND**: [LEINWAND/javascript](https://github.com/LEINWAND/javascript)
3555 | - **Lonely Planet**: [lonelyplanet/javascript](https://github.com/lonelyplanet/javascript)
3556 | - **M2GEN**: [M2GEN/javascript](https://github.com/M2GEN/javascript)
3557 | - **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript)
3558 | - **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript)
3559 | - **MitocGroup**: [MitocGroup/javascript](https://github.com/MitocGroup/javascript)
3560 | - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript)
3561 | - **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript)
3562 | - **Muber**: [muber](https://github.com/muber/)
3563 | - **National Geographic**: [natgeo](https://github.com/natgeo/)
3564 | - **Nimbl3**: [nimbl3/javascript](https://github.com/nimbl3/javascript)
3565 | - **Nulogy**: [nulogy/javascript](https://github.com/nulogy/javascript)
3566 | - **Orange Hill Development**: [orangehill/javascript](https://github.com/orangehill/javascript)
3567 | - **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript)
3568 | - **OutBoxSoft**: [OutBoxSoft/javascript](https://github.com/OutBoxSoft/javascript)
3569 | - **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript)
3570 | - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide)
3571 | - **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript)
3572 | - **React**: [facebook.github.io/react/contributing/how-to-contribute.html#style-guide](https://facebook.github.io/react/contributing/how-to-contribute.html#style-guide)
3573 | - **REI**: [reidev/js-style-guide](https://github.com/rei/code-style-guides/)
3574 | - **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide)
3575 | - **Sainsbury's Supermarkets**: [jsainsburyplc](https://github.com/jsainsburyplc)
3576 | - **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
3577 | - **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
3578 | - **Sourcetoad**: [sourcetoad/javascript](https://github.com/sourcetoad/javascript)
3579 | - **Springload**: [springload](https://github.com/springload/)
3580 | - **StratoDem Analytics**: [stratodem/javascript](https://github.com/stratodem/javascript)
3581 | - **SteelKiwi Development**: [steelkiwi/javascript](https://github.com/steelkiwi/javascript)
3582 | - **StudentSphere**: [studentsphere/javascript](https://github.com/studentsphere/guide-javascript)
3583 | - **SwoopApp**: [swoopapp/javascript](https://github.com/swoopapp/javascript)
3584 | - **SysGarage**: [sysgarage/javascript-style-guide](https://github.com/sysgarage/javascript-style-guide)
3585 | - **Syzygy Warsaw**: [syzygypl/javascript](https://github.com/syzygypl/javascript)
3586 | - **Target**: [target/javascript](https://github.com/target/javascript)
3587 | - **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
3588 | - **The Nerdery**: [thenerdery/javascript-standards](https://github.com/thenerdery/javascript-standards)
3589 | - **T4R Technology**: [T4R-Technology/javascript](https://github.com/T4R-Technology/javascript)
3590 | - **VoxFeed**: [VoxFeed/javascript-style-guide](https://github.com/VoxFeed/javascript-style-guide)
3591 | - **WeBox Studio**: [weboxstudio/javascript](https://github.com/weboxstudio/javascript)
3592 | - **Weggo**: [Weggo/javascript](https://github.com/Weggo/javascript)
3593 | - **Zillow**: [zillow/javascript](https://github.com/zillow/javascript)
3594 | - **ZocDoc**: [ZocDoc/javascript](https://github.com/ZocDoc/javascript)
3595 |
3596 | **[⬆ başa dön](#İçindekiler)**
3597 |
3598 | ## Çeviri
3599 |
3600 | Bu rehbere farklı dillerden de erişilebilir:
3601 |
3602 | -  **Brazilian Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide)
3603 | -  **Bulgarian**: [borislavvv/javascript](https://github.com/borislavvv/javascript)
3604 | -  **Catalan**: [fpmweb/javascript-style-guide](https://github.com/fpmweb/javascript-style-guide)
3605 | -  **Chinese (Simplified)**: [yuche/javascript](https://github.com/yuche/javascript)
3606 | -  **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript)
3607 | -  **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
3608 | -  **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
3609 | -  **Italian**: [sinkswim/javascript-style-guide](https://github.com/sinkswim/javascript-style-guide)
3610 | -  **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide)
3611 | -  **Korean**: [ParkSB/javascript-style-guide](https://github.com/ParkSB/javascript-style-guide)
3612 | -  **Russian**: [leonidlebedev/javascript-airbnb](https://github.com/leonidlebedev/javascript-airbnb)
3613 | -  **Spanish**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide)
3614 | -  **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide)
3615 | -  **Turkish**: [eraycetinay/javascript](https://github.com/eraycetinay/javascript)
3616 | -  **Ukrainian**: [ivanzusko/javascript](https://github.com/ivanzusko/javascript)
3617 | -  **Vietnam**: [hngiang/javascript-style-guide](https://github.com/hngiang/javascript-style-guide)
3618 |
3619 | ## Kılavuz Kılavuzu
3620 |
3621 | - [Reference](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide)
3622 |
3623 | ## JavaScript Sohbet Kanalı
3624 |
3625 | - [gitter](https://gitter.im/airbnb/javascript)'dan ulaşabilirsiniz.
3626 |
3627 | ## Katkıda Bulunanlar
3628 |
3629 | - [Katkıda Bulunanları Görüntüle](https://github.com/airbnb/javascript/graphs/contributors)
3630 |
3631 | ## Lisans
3632 |
3633 | (The MIT License)
3634 |
3635 | Copyright (c) 2012 Airbnb
3636 |
3637 | Permission is hereby granted, free of charge, to any person obtaining
3638 | a copy of this software and associated documentation files (the
3639 | 'Software'), to deal in the Software without restriction, including
3640 | without limitation the rights to use, copy, modify, merge, publish,
3641 | distribute, sublicense, and/or sell copies of the Software, and to
3642 | permit persons to whom the Software is furnished to do so, subject to
3643 | the following conditions:
3644 |
3645 | The above copyright notice and this permission notice shall be
3646 | included in all copies or substantial portions of the Software.
3647 |
3648 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
3649 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3650 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3651 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
3652 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
3653 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
3654 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3655 |
3656 | **[⬆ başa dön](#İçindekiler)**
3657 |
3658 | ## Değişiklikler
3659 |
3660 | 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.
3661 |
3662 | # };
3663 |
--------------------------------------------------------------------------------