# new Yapıcı Operatörü

Bizler şu ana kadar değişkenleri özüne uygun (literal) bir şekilde oluşturduk. Yani:

{% code lineNumbers="true" %}

```javascript
let str = "Karakter",
    sayi = 123;
alert( typeof(str) ); //string
alert( typeof(sayi) ); //number
```

{% endcode %}

Değişkenleri, tipinin özellik ve metotlarına sahip bir '*nesne*' olarak oluşturmak da mümkün.  Bunu yapıcı bir fonksiyon olan **`new`** operatörü ile yaparız. Deneyelim.&#x20;

{% code lineNumbers="true" %}

```javascript
let str = new String("new Operatörü"); // yeni bir 'String Nesnesi'
alert(str); // Aynı string gibi ekrana basıldı.
alert( str[1] ); // Aynı string gibi 'e' çıktısı verdi
alert( str.slice(0,3) ); //// Aynı string gibi 'new' çıktısı verdi
```

{% endcode %}

**`new`** operatörü ile oluşturulan tüm *numuneler* **`object`** tipinde olur.

{% code lineNumbers="true" %}

```javascript
let str = new String("new Operatörü");
alert( typeof(str) ); // string değil 'object'
```

{% endcode %}

Normalde ilkel tipler doğrudan değeri tutarlar fakat **`new`** ile deklare edilen değişkenler aksi yapılmamışsa belleğin [heap](https://hanuce.gitbook.io/javascript-egitimi/referans-reference-veri-tipleri) bölümünde referans (adres) tutarlar.

**`new`** operatörüyle oluşturulan *numune*, örneklendirilen öğenin (**`string`**, **`number`**, vs.) boş bir modelinden (***prototip***) oluşturulur. Bu sebeple numuneler, örneklendirilen öğenin referansını tutmaz, heap bölümünde kendine ait bir referansı olur. Yani:

{% code lineNumbers="true" %}

```javascript
let str = new String("new Operatörü");
let str2 = str // veya 'new String(str);' olarak da deneyebilirsiniz.
alert(str2); // 'new Operatörü' çıktısı
str = 'Yeni değer';
alert(str2); // yine 'new Operatörü' çıktısı alınır.
//str'nin değerinin değişmesinden etkilenmedi. Bağımısz bir kopya
```

{% endcode %}

**`Object.assign()`** ile bir nesneden yeni bir nesne oluşturmak istediğimizde yaptığımız gibi fakat daha veciz bir şekilde. Örnek.

{% code lineNumbers="true" %}

```javascript
let isci = {
    tcNo:12345678900,
    isim:'Çetin KAYA',
};
// Object.assign() ile boş bir örnekten (prototip) değil kendisinden bir kopya
let yeniIsci = Object.assign( {}, isci );
alert(yeniIsci.tcNo); // oluşturulduğu nesne ile aynı değerlere sahip, boş değil.
```

{% endcode %}

Bir *numune* oluşturmak için bu işlemi **`new`** operatörü ile yapalım. Fakat öncesinde **`isci`** öğesini bir fonksiyon halinde yapılandıralım.

{% code lineNumbers="true" %}

```javascript
// isci öğesini bir fonksiyon haline getirerek yapılandıralım.
function Isci(tcNo,isim) {
    this.tcNo = tcNo;
    this.isim = isim;
    this.kendiniTanit = function() {
        return alert(`TCNO: ${this.tcNo}, İSİM: ${this.isim}`);
    }
}
// new operatörü ile prototipten kopyalar yapalım
let isci1 = new Isci('12345','Ahmet'); // her bir isci prototipten oluşur.
let isci2 = new Isci('54321','Mehmet'); // her bir isci prototipten oluşur.

isci1.kendiniTanit();
isci2.kendiniTanit();
alert( typeof(isci1) ); //tipi 'object'
```

{% endcode %}

**`new`** operatörü ile oluşturulan *numunelerde* oluşturulduğu öğenin ( **`string`**,  **`number`**, **`function`** vb. ) tüm özellik ve metotları bulunur.

{% hint style="info" %}
Kendisinden **`new`** operatörü ile *numuneler* üretilecek fonksiyon isimlerinin ilk harfi büyük yazılır. Bu prototipler için bir gelenektir, zorunluluk değil.
{% endhint %}

Öğelerin bir prototipi (tüm özelliklerine haiz boş hali) vardır. Peki bir öğenin tüm *numunelerine* sonradan bir özellik eklemek istersek ? Bunun için öğenin **`prototype`**'ini kullanacağız. Önceki koddan devam edersek.

<pre class="language-javascript" data-line-numbers><code class="lang-javascript">isci1.kidem = '10'; // yeni özellik ekledik.
alert(isci1.kidem); //10 çıktısı verir.
alert(isci2.kidem); // 'undefined' çıktısı verir çünkü isci2 nesnesine eklemedik.

// tüm isci örneklerine yeni bir özelliği prototip olarak ekleyelim.
<strong>Isci.prototype.kidem = '0'; // tüm örnekler için varsayılan değer 0 atadık.
</strong>alert(isci2.kidem); // 0 çıktısı verir.
let isci3 = new Isci('98775', 'Veli');
alert(isci3.kidem); // 0 çıktısı verir.
</code></pre>

Bazı öğeler (sınıf, nesne veya fonksiyon) özüne uygun (literal) bir şekilde oluşturulabileceği gibi **`new`** operatörü ile de oluşturulabilir. Bunlar:

* **`new Array()`**
* **`new Object()`**
* **`new String()`**
* **`new Number()`**
* **`new BigInt()`**
* **`new Boolean()`**
* **`new Function()`**

Fakat bazı öğeleri oluşturmanın doğrudan bir yöntemi (literal) yoktur. Bunları sadece **`new`** operatörü ile oluşturabiliriz. Örnek:

* **`new Map()`**
* **`new Set()`**
* **`new Symbol()`**
* **`new Error()`**
