4.[Nesneler ve Veri Yapıları](#nesneler-ve-veri-yapilari)
5.[Sınıflar](#classes)
6.[SOLID](#solid)
7.[Test](#test)
8.[Eşzamanlılık](#eszamanlilik)
9.[Hata Yakalama](#hata-yakalama)
10.[Yazım Şekli](#yazim-sekli)
11.[Yorumlar](#yorumlar)
12.[Translation](#translation)
## Giriş

Yazılım mühendisliği prensipleri, Robert C. Martin'in
[*Clean Code*](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) isimli kitabından alınmış, JavaScript için uyarlanmıştır. Bu bir stil rehber değildir. Bu JavaScript ile
[readable, reusable, ve refactorable](https://github.com/ryanmcdermott/3rs-of-software-architecture) yazılımlar üretmek için bir rehberdir..
Burada yazılan prensiplere sıkı bir şekilde uymanız gerekmez belki bazı kurallar herkesçe kabul edilecektir. Burada yazanlar kurallar ve daha fazlası değil. Ancak bu kurallar *Clean Code* yazarlarının uzun yıllara dayanan deneyimleri sonucu ortaya çıktığı için dikkate almanız iyi olabilir.
Yazılım mühendisliği konusundaki çalışmalarımız 50 yılın biraz üzerinde ve hala çok fazla şey öğreniyoruz. Yazılım mimarisi, mimarlığın kendisi kadar eski olduğunda belki de uyulması gereken daha zor kurallara sahip olacağız. Şimdilik, bu kılavuzların sizin ve ekibinizin ürettiği JavaScript kodunun kalitesini değerlendirmek için bir mihenk taşı olarak hizmet etmesine izin verin.
Son bir şey daha: Bunları biliyor olmak sizi hemen mükemmel bir yazılım geliştirici yapmaz ve bu kuralları bilerek geçirdiğiniz yıllar hata yapmayacağınız anlamına da gelmez. Her kod parçası bir taslak olarak başlar, tıpkı ıslak bir kilin son halini alması gibi de devam eder. Son olarak takım arkadaşlarımızla incelemeler yaparken kötü görünen kısımları yok eder. Gelişime ihtiyacı olan kodun ilk hali için kendinize kızmayın. Bunun yerine kodu dövün :)
## **Değişkenler**
### Anlamlı ve belirli değişken isimleri kullanın
**Kötü:**
```javascript
constyyyymmdstr=moment().format('YYYY/MM/DD');
```
**İyi:**
```javascript
constmevcutTarih=moment().format('YYYY/MM/DD');
```
**[⬆ en başa dön](#icindekiler)**
### Aynı türde değişkenler için aynı kelimeleri kullanın
**Kötü:**
```javascript
kullaniciBilgisiGetir();
musteriVerisiGetir();
musteriKayitlariGetir();
```
**İyi:**
```javascript
kullaniciGetir();
```
**[⬆ en başa dön](#icindekiler)**
### Aranabilir isimler kullanın
Yazacağımızdan daha fazla kod okuyacağız. Bu yazdığımız kodun okunabilir ve aranabilir olması açısından önemlidir. Değişkenleri kötü bir şekilde adlandırmayarak programımızı anlamaya çalışan kod okuyucularına zarar vermeyiz. İsimleri aranabilir yapın. [buddy.js](https://github.com/danielstjules/buddy.js) ve [ESLint](https://github.com/eslint/eslint/blob/660e0918933e6e7fede26bc675a0763a6b357c94/docs/rules/no-magic-numbers.md) gibi araçlar tanımlanmamış sabit değerleri constant olarak tanımlamanıza yardımcı olabilir.
**Kötü:**
```javascript
// Bu 86400000 ne olabilir??
setTimeout(havalandirmayiCalistir,86400000);
```
**İyi:**
```javascript
// Bu türden tanımlamaları büyük harfler ve alt çizgiler içerecek şekilde belirtin.
Eğer sınıf ya da nesne adından ne yaptığı anlaşılıyorsa, tekrar olarak değişkenler içinde onu anlatan isimlendirmeler yapmayın.
**Kötü:**
```javascript
constAraba={
arabaUret:'Honda',
arabaModeli:'Accord',
arabaRengi:'Mavi'
};
functionarabayiBoya(araba){
araba.arabaRengi='Kırmızı';
}
```
**İyi:**
```javascript
constAraba={
uret:'Honda',
model:'Accord',
renk:'Mavi'
};
functionarabayiBoya(araba){
araba.renk='Kırmızı';
}
```
**[⬆ en başa dön](#icindekiler)**
### Kısa Mantıksal İfadeler ya da Koşullar Yerine Varsayılan Argümanlar Kullanın
Varsayılan argümanlar çoğunlukla kısa mantıksa ifadelerden daha temiz bir kullanıma sahiptir. Varsayılan argümanların sadece undefined argümanlar geçerliyse çalışacağını unutmayın. Diğer falsy olarak kabul edilen değerler varsayılan argümanı değiştirecektir. Bunlar `''`, `""`, `false`, `null`, `0`, ve `NaN` olarak gösterilebilir.
Flags tell your user that this function does more than one thing. Functions should do one thing. Split out your functions if they are following different code paths based on a boolean.
**Kötü:**
```javascript
functioncreateFile(name,temp){
if(temp){
fs.create(`./temp/${name}`);
}else{
fs.create(name);
}
}
```
**İyi:**
```javascript
functioncreateFile(name){
fs.create(name);
}
functioncreateTempFile(name){
createFile(`./temp/${name}`);
}
```
**[⬆ en başa dön](#icindekiler)**
### Avoid Side Effects (part 1)
A function produces a side effect if it does anything other than take a value in
and return another value or values. A side effect could be writing to a file,
modifying some global variable, or accidentally wiring all your money to a
stranger.
Now, you do need to have side effects in a program on occasion. Like the previous
example, you might need to write to a file. What you want to do is to
centralize where you are doing this. Don't have several functions and classes
that write to a particular file. Have one service that does it. One and only one.
The main point is to avoid common pitfalls like sharing state between objects
without any structure, using mutable data types that can be written to by anything,
and not centralizing where your side effects occur. If you can do this, you will
be happier than the vast majority of other programmers.
**Kötü:**
```javascript
// Global variable referenced by following function.
// If we had another function that used this name, now it'd be an array and it could break it.
letname='Ryan McDermott';
functionsplitIntoFirstAndLastName(){
name=name.split(' ');
}
splitIntoFirstAndLastName();
console.log(name);// ['Ryan', 'McDermott'];
```
**İyi:**
```javascript
functionsplitIntoFirstAndLastName(name){
returnname.split(' ');
}
constname='Ryan McDermott';
constnewName=splitIntoFirstAndLastName(name);
console.log(name);// 'Ryan McDermott';
console.log(newName);// ['Ryan', 'McDermott'];
```
**[⬆ en başa dön](#icindekiler)**
### Avoid Side Effects (part 2)
In JavaScript, primitives are passed by value and objects/arrays are passed by
reference. In the case of objects and arrays, if your function makes a change
in a shopping cart array, for example, by adding an item to purchase,
then any other function that uses that `cart` array will be affected by this
addition. That may be great, however it can be bad too. Let's imagine a bad
situation:
The user clicks the "Purchase", button which calls a `purchase` function that
spawns a network request and sends the `cart` array to the server. Because
of a bad network connection, the `purchase` function has to keep retrying the
request. Now, what if in the meantime the user accidentally clicks "Add to Cart"
button on an item they don't actually want before the network request begins?
If that happens and the network request begins, then that purchase function
will send the accidentally added item because it has a reference to a shopping
cart array that the `addItemToCart` function modified by adding an unwanted
item.
A great solution would be for the `addItemToCart` to always clone the `cart`,
edit it, and return the clone. This ensures that no other functions that are
holding onto a reference of the shopping cart will be affected by any changes.
Two caveats to mention to this approach:
1. There might be cases where you actually want to modify the input object,
but when you adopt this programming practice you will find that those cases
are pretty rare. Most things can be refactored to have no side effects!
2. Cloning big objects can be very expensive in terms of performance. Luckily,
this isn't a big issue in practice because there are
[great libraries](https://facebook.github.io/immutable-js/) that allow
this kind of programming approach to be fast and not as memory intensive as
it would be for you to manually clone objects and arrays.
**Kötü:**
```javascript
constaddItemToCart=(cart,item)=>{
cart.push({item,date:Date.now()});
};
```
**İyi:**
```javascript
constaddItemToCart=(cart,item)=>{
return[...cart,{item,date:Date.now()}];
};
```
**[⬆ en başa dön](#icindekiler)**
### Don't write to global functions
Polluting globals is a bad practice in JavaScript because you could clash with another
library and the user of your API would be none-the-wiser until they get an
exception in production. Let's think about an example: what if you wanted to
extend JavaScript's native Array method to have a `diff` method that could
show the difference between two arrays? You could write your new function
to the `Array.prototype`, but it could clash with another library that tried
to do the same thing. What if that other library was just using `diff` to find
the difference between the first and last elements of an array? This is why it
would be much better to just use ES2015/ES6 classes and simply extend the `Array` global.
There's no excuse to not write tests. There are [plenty of good JS test frameworks](http://jstherightway.org/#testing-tools), so find one that your team prefers.
When you find one that works for your team, then aim to always write tests
for every new feature/module you introduce. If your preferred method is
Test Driven Development (TDD), that is great, but the main point is to just
make sure you are reaching your coverage goals before launching any feature,
or refactoring an existing one.
### Single concept per test
**Kötü:**
```javascript
importassertfrom'assert';
describe('MakeMomentJSGreatAgain',()=>{
it('handles date boundaries',()=>{
letdate;
date=newMakeMomentJSGreatAgain('1/1/2015');
date.addDays(30);
assert.equal('1/31/2015',date);
date=newMakeMomentJSGreatAgain('2/1/2016');
date.addDays(28);
assert.equal('02/29/2016',date);
date=newMakeMomentJSGreatAgain('2/1/2015');
date.addDays(28);
assert.equal('03/01/2015',date);
});
});
```
**İyi:**
```javascript
importassertfrom'assert';
describe('MakeMomentJSGreatAgain',()=>{
it('handles 30-day months',()=>{
constdate=newMakeMomentJSGreatAgain('1/1/2015');
date.addDays(30);
assert.equal('1/31/2015',date);
});
it('handles leap year',()=>{
constdate=newMakeMomentJSGreatAgain('2/1/2016');
date.addDays(28);
assert.equal('02/29/2016',date);
});
it('handles non-leap year',()=>{
constdate=newMakeMomentJSGreatAgain('2/1/2015');
date.addDays(28);
assert.equal('03/01/2015',date);
});
});
```
**[⬆ en başa dön](#icindekiler)**
## **Concurrency**
### Use Promises, not callbacks
Callbacks aren't clean, and they cause excessive amounts of nesting. With ES2015/ES6,