---
title: 'Özellik Tanımlayıcıları'
source: 'https://academia.sh/tr/kurslar/javascript-nesne-modeli/ozellik-tanimlayicilari'
course: "JavaScript'te Nesneler ve Fonksiyonlar"
language: tr
updated: '2026-08-17T18:09:50+00:00'
license: 'CC BY-SA 4.0'
---

# Özellik Tanımlayıcıları

Bir özelliğin değerinin yanında taşıdığı yazılabilirlik, sayılabilirlik ve yapılandırılabilirlik bayrakları; erişimci özellikler ve tanımlayıcıları koruyan kopyalama.

Önceki ders iki kez aynı yere geldi: sınıf yöntemleri `for...in` çıktısında görünmüyor,
elle yazılan atamalar görünüyordu; ve `okunanDeger` bir okuma gibi yazıldığı hâlde
fonksiyon çalıştırıyordu. İkisi de tek bir gerçeğin sonucudur.

Bir özellik yalnızca "ad → değer" çiftinden ibaret değildir. Her özelliğin yanında,
davranışını belirleyen bir **özellik tanımlayıcısı (property descriptor)** durur. Bu ders
tanımlayıcının alanlarını tek tek açar; ardından değer yerine fonksiyon taşıyan
erişimci özellikleri ele alır.

## Tanımlayıcıyı Okumak

`Object.getOwnPropertyDescriptor`, bir nesnenin **kendi** özelliğinin tanımlayıcısını
döndürür. Veri özelliklerinde dört alan bulunur: `value`, `writable`, `enumerable`,
`configurable`.

```js
function bayraklar(nesne, ad) {
  const tanim = Object.getOwnPropertyDescriptor(nesne, ad);
  if (tanim === undefined) return `${ad}: tanim yok`;
  if ("value" in tanim) {
    return `${ad}: veri, yazilabilir=${tanim.writable}, sayilabilir=${tanim.enumerable}, yapilandirilabilir=${tanim.configurable}`;
  }
  return `${ad}: erisimci, okuyucu=${typeof tanim.get}, yazici=${typeof tanim.set}, sayilabilir=${tanim.enumerable}`;
}

class OlcumKaydi {
  constructor(sensor, deger) {
    this.sensor = sensor;
    this.deger = deger;
  }
  bicimle() {
    return `${this.sensor}: ${this.deger}`;
  }
}

const kayit = new OlcumKaydi("S-01", 21.4);
const duzKayit = { sensor: "S-02", deger: 19.8 };

Object.defineProperty(duzKayit, "birim", { value: "santigrat" });

console.log(bayraklar(kayit, "sensor"));
console.log(bayraklar(OlcumKaydi.prototype, "bicimle"));
console.log(bayraklar(duzKayit, "sensor"));
console.log(bayraklar(duzKayit, "birim"));
console.log(bayraklar(kayit, "bicimle"));
```

```
sensor: veri, yazilabilir=true, sayilabilir=true, yapilandirilabilir=true
bicimle: veri, yazilabilir=true, sayilabilir=false, yapilandirilabilir=true
sensor: veri, yazilabilir=true, sayilabilir=true, yapilandirilabilir=true
birim: veri, yazilabilir=false, sayilabilir=false, yapilandirilabilir=false
bicimle: tanim yok
```

Üç kural çıkar. Sıradan atamayla ya da nesne değişmeziyle üretilen özelliklerin üç bayrağı
da açıktır. Sınıf yöntemleri sayılamaz olarak tanımlanır — önceki dersteki `for...in`
farkının kaynağı budur. `Object.defineProperty` çağrısında **belirtilmeyen her bayrak
kapalı sayılır**; bu yüzden `birim` özelliği yazılamaz, sayılamaz ve yapılandırılamaz
çıkmıştır. Son satır ise işlevin adındaki "kendi" sözcüğünü hatırlatır: `bicimle`
prototipte durduğu için kayıt üzerinde tanımı yoktur.

## Yazılabilirlik

`writable` bayrağı kapalıysa atama değeri değiştirmez. Değiştirmemenin iki farklı biçimi
vardır ve aradaki fark, kodun katı kipte çalışıp çalışmadığına bağlıdır.

```js
const kayit = { sensor: "S-01", deger: 21.4 };

Object.defineProperty(kayit, "birim", {
  value: "santigrat",
  writable: false,
  enumerable: true,
  configurable: false,
});

console.log(kayit.birim);

try {
  kayit.birim = "fahrenhayt";
} catch (hata) {
  console.log(`${hata.constructor.name} yakalandi`);
}
console.log(kayit.birim);

function katiOlmayanYazma(nesne) {
  return new Function("n", "n.birim = 'fahrenhayt'; return n.birim;")(nesne);
}
console.log(katiOlmayanYazma(kayit));

try {
  Object.defineProperty(kayit, "birim", { value: "kelvin" });
} catch (hata) {
  console.log(`${hata.constructor.name} yakalandi`);
}
console.log(kayit.birim);
```

```
santigrat
TypeError yakalandi
santigrat
santigrat
TypeError yakalandi
santigrat
```

Modül dosyaları ve sınıf gövdeleri katı kipte çalışır; orada yazılamayan özelliğe atama
hata yükseltir. `new Function` ile üretilen gövde katı kipte değildir, bu yüzden aynı
atama sessizce başarısız olur — dördüncü satırdaki değişmemiş değer bunu gösterir. Sessiz
başarısızlık, hatanın atamadan çok sonra fark edilmesine yol açtığı için katı kip
tercih edilir.

Son iki satır `configurable` bayrağının etkisidir. Yapılandırılabilirlik kapatıldığında
tanımlayıcı bir daha değiştirilemez ve özellik silinemez; bu, geri alınamayan tek
bayraktır. Bu nedenle `configurable: false` bilinçli bir karar olmalıdır.

## Sayılabilirlik

`enumerable` bayrağı, özelliğin listelemelere girip girmeyeceğini belirler. Etkisi geniş
bir işlem kümesine yayılır.

```js
const kayit = { sensor: "S-01", deger: 21.4 };

Object.defineProperty(kayit, "kaynakDosya", {
  value: "olcum-2.csv",
  writable: true,
  enumerable: false,
  configurable: true,
});

console.log(kayit.kaynakDosya);
console.log(Object.keys(kayit).join(","));
console.log(Object.getOwnPropertyNames(kayit).join(","));
console.log(JSON.stringify(kayit));
console.log(JSON.stringify({ ...kayit }));
console.log(JSON.stringify(Object.assign({}, kayit)));
console.log("kaynakDosya" in kayit);
console.log(Object.entries(kayit).length);
```

```
olcum-2.csv
sensor,deger
sensor,deger,kaynakDosya
{"sensor":"S-01","deger":21.4}
{"sensor":"S-01","deger":21.4}
{"sensor":"S-01","deger":21.4}
true
2
```

Özellik okunabilir durumdadır ve `in` işleci onu görür; ama `Object.keys`,
`Object.entries`, `JSON.stringify`, nesne yayma ve `Object.assign` onu atlar.
`Object.getOwnPropertyNames` ise sayılabilirliğe bakmaz, bu yüzden gizli kalan
özellikleri denetlemenin yolu odur.

Buradan pratik bir kural çıkar: **veriye eşlik eden ama verinin parçası olmayan
bilgiler** — kaynak dosya adı, iç sayaçlar, önbellek alanları — sayılamaz tanımlanırsa
dizileştirme ve kopyalama işlemlerine kendiliğinden karışmaz. Aynı sonucu simge (symbol)
anahtarlı özellikler de verir; onlar da `Object.keys` ve `JSON.stringify` çıktılarına
girmez.

## Erişimci Özellikler

İkinci tanımlayıcı türünde `value` ve `writable` yerine `get` ve `set` fonksiyonları
bulunur. Böyle bir özelliğe **erişimci (accessor)** denir: okuma `get` fonksiyonunu,
yazma `set` fonksiyonunu çalıştırır.

Erişimcinin değeri, hesaplanan bir büyüklüğü özellik gibi sunmasıdır. Ölçüm kaydında
okunan değer, ham değer ile kalibrasyon kaymasının toplamıdır; bunu bir yöntem yerine
erişimci yapmak, çağıranı hesabın varlığından habersiz bırakır.

```js
const olcumDavranisi = {};

Object.defineProperty(olcumDavranisi, "okunanDeger", {
  get() {
    return this.deger + this.kayma;
  },
  set(yeniDeger) {
    if (typeof yeniDeger !== "number" || Number.isNaN(yeniDeger)) {
      throw new TypeError("okunan deger sayi olmalidir");
    }
    this.deger = yeniDeger - this.kayma;
  },
  enumerable: false,
  configurable: true,
});

function olcumKaydi(sensor, deger, kayma) {
  const kayit = Object.create(olcumDavranisi);
  kayit.sensor = sensor;
  kayit.deger = deger;
  kayit.kayma = kayma;
  return kayit;
}

const kayit = olcumKaydi("S-01", 21.4, -0.4);

console.log(kayit.okunanDeger);
kayit.okunanDeger = 25;
console.log(kayit.deger);
console.log(kayit.okunanDeger);

try {
  kayit.okunanDeger = "yirmi";
} catch (hata) {
  console.log(`${hata.constructor.name}: ${hata.message}`);
}

console.log(Object.hasOwn(kayit, "okunanDeger"));
console.log(Object.hasOwn(olcumDavranisi, "okunanDeger"));
console.log(JSON.stringify(kayit));
```

```
21
25.4
25
TypeError: okunan deger sayi olmalidir
false
true
{"sensor":"S-01","deger":25.4,"kayma":-0.4}
```

Erişimci prototipte tanımlıdır; kaydın kendi özelliği değildir. Buna karşın `get` ve
`set` gövdelerindeki `this`, erişimin yapıldığı nesneye — yani kaydın kendisine —
bağlanır. Zincirde bulunan bir fonksiyon, çağrıldığı nesnenin verisiyle çalışır; bu
kuralın tamamı sonraki konunun ilk dersinde ele alınacaktır.

Yazıcı fonksiyon, Programlama Temelleri kursundaki Nesneye Dayalı Programlamaya Giriş
dersinde tanıtılan **sınıf değişmezini** korumanın doğrudan yoludur: geçersiz değer
nesneye hiç girmez. Ayrıca erişimci sayılamaz tanımlandığı için dizileştirmeye girmez;
son satırda yalnızca ham veri alanları görünür. Bu, hesaplanmış değerlerin depolanan
veriyle karışmamasını sağlar.

Sınıf gövdesindeki `get` ve `set` sözcükleri bu tanımın kısaltmasıdır; ürettikleri
erişimci de `prototype` nesnesine, sayılamaz olarak yazılır.

## Tanımlayıcıları Koruyan Kopyalama

Bir nesneyi kopyalamanın alışılmış yolları tanımlayıcıları taşımaz. Nesne yayma ve
`Object.assign`, kaynaktaki her özelliği **okur** ve hedefe sıradan bir veri özelliği
olarak **yazar**. Erişimciler bu işlemde donmuş değere dönüşür.

```js
const kaynak = {
  sensor: "S-01",
  deger: 21.4,
  get etiket() {
    return `${this.sensor}/${this.deger}`;
  },
};

const yayilmis = { ...kaynak };
const tanimlaKopya = Object.defineProperties(
  Object.create(Object.getPrototypeOf(kaynak)),
  Object.getOwnPropertyDescriptors(kaynak),
);

console.log(kaynak.etiket);
console.log(yayilmis.etiket);
console.log(tanimlaKopya.etiket);

kaynak.deger = 30;
yayilmis.deger = 30;
tanimlaKopya.deger = 30;

console.log(kaynak.etiket);
console.log(yayilmis.etiket);
console.log(tanimlaKopya.etiket);

console.log(typeof Object.getOwnPropertyDescriptor(yayilmis, "etiket").get);
console.log(typeof Object.getOwnPropertyDescriptor(tanimlaKopya, "etiket").get);
```

```
S-01/21.4
S-01/21.4
S-01/21.4
S-01/30
S-01/21.4
S-01/30
undefined
function
```

Yayma ile üretilen kopyada `etiket` artık hesaplanmaz; kopyalama anındaki metni taşıyan
sabit bir veri özelliğidir, bu yüzden `deger` değiştiğinde eskisini göstermeye devam eder.
`Object.getOwnPropertyDescriptors` ile `Object.defineProperties` birlikte kullanıldığında
hem erişimciler hem de bayraklar korunur; `Object.create` çağrısı da prototip bağını
taşır. Kopyalamanın genel sorunu — hangi bilginin taşındığı, hangisinin düştüğü — kursun
son dersinde bütünüyle ele alınacaktır.

## Özet

- Her özellik, değerinin yanında `writable`, `enumerable`, `configurable` bayraklarını
  taşır; `Object.getOwnPropertyDescriptor` bunları okur.
- `Object.defineProperty` çağrısında belirtilmeyen bayraklar kapalı sayılır; atama ile
  üretilen özelliklerde ise üçü de açıktır.
- Yazılamayan özelliğe atama katı kipte hata yükseltir, katı olmayan kipte sessizce
  başarısız olur; `configurable: false` geri alınamaz.
- Sayılamaz özellikler `Object.keys`, `Object.entries`, `JSON.stringify`, yayma ve
  `Object.assign` sonuçlarına girmez; `Object.getOwnPropertyNames` ile görünür.
- Erişimci özellikte okuma ve yazma birer fonksiyon çalıştırır; yazıcı, geçersiz değerin
  nesneye girmesini engelleyerek sınıf değişmezini korur.
- Yayma ve `Object.assign` tanımlayıcıları taşımaz; erişimciyi sabit değere çevirir.

## Sonraki Adım

`writable: false` tek bir özelliği kilitler. Bir nesnenin tamamının değişmesini önlemek,
ona yeni özellik eklenmesini yasaklamak ya da yalnızca var olan alanların değerini
değiştirilebilir bırakmak için özellik başına tanım yazmak zahmetlidir. Sonraki ders
nesnenin bütününe uygulanan dondurma ve mühürleme işlemlerini, bunların ne kadar derine
indiğini ve değişiklik gerektiğinde yeni nesne üretmenin kalıplarını ele alacak.
