new Yapıcı Operatörü

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

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

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.

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

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

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

Normalde ilkel tipler doğrudan değeri tutarlar fakat new ile deklare edilen değişkenler aksi yapılmamışsa belleğin heap 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:

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

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

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.

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.

// 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'

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

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.

Öğ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.

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.
Isci.prototype.kidem = '0'; // tüm örnekler için varsayılan değer 0 atadık.
alert(isci2.kidem); // 0 çıktısı verir.
let isci3 = new Isci('98775', 'Veli');
alert(isci3.kidem); // 0 çıktısı verir.

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()

Last updated