JavaScript'te Object üzerinde tanımlı statik metotlar, bir nesnenin anahtarlarını, değerlerini ve anahtar-değer çiftlerini dizi olarak almanızı, nesneleri birleştirmenizi, dondurmanızı ve gruplamanızı sağlar. En çok kullanılanlar Object.keys(), Object.values(), Object.entries(), Object.fromEntries(), Object.assign(), Object.freeze() ve yeni eklenen Object.groupBy() metotlarıdır.
Bu metotlar obj.keys() gibi nesnenin kendisi üzerinden değil, Object.keys(obj) biçiminde çağrılır. Aşağıda her birini çalışan örneklerle anlatıyor, sonunda bir nesnenin alanlarının arkasındaki "property descriptor" (özellik tanımlayıcı) kavramına kısaca değiniyoruz. Dil temellerine genel bakış için JavaScript öğrenme rehberine bakabilirsiniz.
Object.keys, Object.values ve Object.entries

Üçü de nesnenin kendi (prototip zincirinden gelmeyen), numaralandırılabilir (enumerable) ve metin anahtarlı özellikleriyle çalışır. keys() anahtarları, values() değerleri, entries() ise [anahtar, değer] çiftlerini dizi olarak döndürür. Sıralama for...in döngüsüyle aynıdır; farkı, for...in döngüsünün prototip zincirindeki özellikleri de gezmesidir.
const ayar = { tema: "koyu", dil: "tr", bildirim: true };
console.log(Object.keys(ayar)); // [ 'tema', 'dil', 'bildirim' ]
console.log(Object.values(ayar)); // [ 'koyu', 'tr', true ]
console.log(Object.entries(ayar));
// [ [ 'tema', 'koyu' ], [ 'dil', 'tr' ], [ 'bildirim', true ] ]
for (const [anahtar, deger] of Object.entries(ayar)) {
console.log(`${anahtar} = ${deger}`);
}
// tema = koyu
// dil = tr
// bildirim = true
console.log(Object.keys(ayar).length); // 3Döngüdeki [anahtar, deger] yazımı dizi destructuring'dir; ayrıntısı destructuring ve spread yazısında. Düz nesnenin eleman sayısını almanın yaygın yolu Object.keys(obj).length olsa da sık ekleme-silme yapılan koleksiyonlarda size özelliği olan Map daha uygundur.
Object.fromEntries: çiftlerden nesne üretmek
Object.fromEntries(), entries() işleminin tersidir: [anahtar, değer] çiftleri üreten herhangi bir iterable'ı (dizi, Map vb.) alıp yeni bir nesne döndürür. Düz nesnelerde map() veya filter() yoktur; entries ile diziye çevirip dizi metotlarını uyguladıktan sonra fromEntries ile geri dönmek yaygın bir kalıptır.
const fiyatlar = { elma: 40, armut: 55, kiraz: 120 };
// 100 ve üzerini çıkar, kalanlara %10 zam yap
const yeni = Object.fromEntries(
Object.entries(fiyatlar)
.filter(([, fiyat]) => fiyat < 100)
.map(([ad, fiyat]) => [ad, Math.round(fiyat * 1.1)]),
);
console.log(yeni); // { elma: 44, armut: 61 }
// Map de bir çift kaynağıdır
const m = new Map([["a", 1], ["b", 2]]);
console.log(Object.fromEntries(m)); // { a: 1, b: 2 }
// URL sorgu dizesini nesneye çevirmek
const q = new URLSearchParams("sayfa=2&sirala=fiyat");
console.log(Object.fromEntries(q)); // { sayfa: '2', sirala: 'fiyat' }Object.assign: kopyalama ve birleştirme

Object.assign(hedef, kaynak1, kaynak2, ...) kaynak nesnelerin kendi ve numaralandırılabilir özelliklerini hedefe yazar ve hedefi döndürür. Aynı anahtar birden çok kaynakta varsa sonraki kaynak kazanır. Önemli nokta: hedef nesne değişir. Yeni bir nesne istiyorsanız ilk argüman olarak boş bir nesne verin.
const varsayilan = { port: 3000, log: false };
const kullanici = { log: true };
const ayar = Object.assign({}, varsayilan, kullanici);
console.log(ayar); // { port: 3000, log: true }
console.log(varsayilan); // { port: 3000, log: false }
// Hedef olarak varsayilan verilirse kendisi değişir
Object.assign(varsayilan, kullanici);
console.log(varsayilan.log); // trueGünümüzde aynı işi çoğunlukla nesne spread sözdizimiyle ({ ...varsayilan, ...kullanici }) yaparız. MDN iki fark sayar: Object.assign() var olan bir nesneyi değiştirebilir ve hedefteki setter fonksiyonlarını tetikler; spread ise her zaman yeni nesne oluşturur ve setter çağırmaz.
Hata davranışı da bilinmeye değer. Hedef null veya undefined ise Object.assign() TypeError fırlatır; kaynaklardan biri null veya undefined ise o kaynak sessizce atlanır. Kaynakları okurken getter fonksiyonlarını çalıştırır, hedefe yazarken setter fonksiyonlarını tetikler. Yazma sırasında bir hata çıkarsa (örneğin hedefteki salt okunur bir alan), o ana kadar yazılmış özellikler hedefte kalır; işlem geri alınmaz.
try {
Object.assign(null, { a: 1 });
} catch (e) {
console.log(e.name); // TypeError
}
console.log(Object.assign({}, null, undefined, { a: 1 })); // { a: 1 }Object.freeze ve Object.seal
Object.freeze() bir nesneye özellik eklenmesini, silinmesini ve var olan veri özelliklerinin değiştirilmesini engeller. Yeni bir kopya üretmez; aldığı nesnenin kendisini dondurup geri döndürür. Değişiklik denemeleri normal kodda sessizce yok sayılır, strict mode içinde ise genellikle TypeError fırlatır.
const sabitler = Object.freeze({ KDV: 0.2, para: "TRY", limit: { gunluk: 5000 } });
sabitler.KDV = 0.5; // sessizce yok sayılır
sabitler.yeni = 1; // eklenmez
console.log(sabitler.KDV, sabitler.yeni); // 0.2 undefined
console.log(Object.isFrozen(sabitler)); // true
// Dondurma sığdır: iç nesne hâlâ değişebilir
sabitler.limit.gunluk = 1;
console.log(sabitler.limit.gunluk); // 1
(function () {
"use strict";
try {
sabitler.para = "USD";
} catch (e) {
console.log(e.constructor.name); // TypeError
}
})();Object.seal() daha gevşektir: özellik eklemeyi ve silmeyi engeller ama yazılabilir özelliklerin değerini değiştirmeye izin verir. İç içe nesneleri tamamen dondurmak istiyorsanız her seviyede freeze çağıran özyinelemeli bir fonksiyon yazmanız gerekir. const anahtar kelimesini bununla karıştırmayın: const yalnızca değişkenin yeniden atanmasını engeller, nesnenin içini değil (bkz. var, let ve const farkı).
Object.groupBy: dizileri gruplamak
Object.groupBy(items, callbackFn) bir iterable'ı, callback fonksiyonun döndürdüğü anahtara göre gruplar. Her anahtarın değeri, o gruba düşen öğelerin dizisidir. Dönen nesne null prototipli bir nesnedir, yani toString gibi miras alınmış özellikler taşımaz. Öğeler kopyalanmaz; gruplardaki nesneler kaynak dizideki nesnelerin kendisidir.
const stok = [
{ ad: "elma", tur: "meyve", adet: 5 },
{ ad: "havuç", tur: "sebze", adet: 0 },
{ ad: "muz", tur: "meyve", adet: 12 },
];
const turlere = Object.groupBy(stok, (u) => u.tur);
console.log(Object.keys(turlere)); // [ 'meyve', 'sebze' ]
console.log(turlere.meyve.map((u) => u.ad)); // [ 'elma', 'muz' ]
const durum = Object.groupBy(stok, ({ adet }) => (adet > 0 ? "var" : "tukendi"));
console.log(durum.tukendi[0].ad); // havuç
console.log(Object.getPrototypeOf(durum)); // nullBu metot gelmeden önce aynı iş genellikle reduce() ile, her anahtar için grubun var olup olmadığını kontrol eden birkaç satırlık bir callback yazılarak yapılırdı. Object.groupBy() bu kalıbı tek çağrıya indirir. Dönen nesne null prototipli olduğu için "constructor" ya da "toString" gibi grup adları miras alınan özelliklerle çakışmaz.
Grup anahtarı metin değil de bir nesne olacaksa aynı işi yapan Map.groupBy() bir Map döndürür. Object.groupBy() görece yeni bir metottur; örnek Node.js 24 ile çalıştı, eski ortamlar için MDN uyumluluk tablosuna bakın.
Property descriptor: bir özelliğin görünmeyen ayarları
Her özelliğin değerinin yanında birkaç gizli niteliği vardır. Veri özelliklerinde value ve writable, erişimci (getter/setter) özelliklerinde get ve set; her ikisinde de enumerable ve configurable bulunur. Object.getOwnPropertyDescriptor() bu kaydı okur, Object.defineProperty() ise bu ayarlarla özellik tanımlar.
const kullanici = { ad: "Ece" };
console.log(Object.getOwnPropertyDescriptor(kullanici, "ad"));
// { value: 'Ece', writable: true, enumerable: true, configurable: true }
Object.defineProperty(kullanici, "id", { value: 42 });
console.log(Object.getOwnPropertyDescriptor(kullanici, "id"));
// { value: 42, writable: false, enumerable: false, configurable: false }
console.log(Object.keys(kullanici)); // [ 'ad' ]
console.log(JSON.stringify(kullanici)); // {"ad":"Ece"}
console.log(kullanici.id); // 42Atama ile oluşturulan özelliklerde bu niteliklerin hepsi true olur. defineProperty ile tanımlarken belirtmediğiniz nitelikler ise varsayılan olarak false olur. Bu yüzden yukarıdaki id alanı Object.keys() ve JSON.stringify() çıktısında görünmez. Object.freeze() da aslında tüm özelliklerin configurable niteliğini, veri özelliklerinde ayrıca writable niteliğini false yapar. Getter ve setter kullanımı için class yazısına bakabilirsiniz.
Hangi metot ne döndürür?

| Metot | Döndürdüğü | Argümanı değiştirir mi |
|---|---|---|
| Object.keys(obj) | anahtar dizisi | hayır |
| Object.values(obj) | değer dizisi | hayır |
| Object.entries(obj) | [anahtar, değer] dizisi | hayır |
| Object.fromEntries(iterable) | yeni nesne | hayır |
| Object.assign(hedef, ...kaynak) | hedef nesnenin kendisi | evet, hedefi |
| Object.freeze(obj) | aynı nesne (dondurulmuş) | evet |
| Object.seal(obj) | aynı nesne (mühürlenmiş) | evet |
| Object.groupBy(items, fn) | null prototipli yeni nesne | hayır |
| Object.hasOwn(obj, anahtar) | true / false | hayır |
| Object.getOwnPropertyDescriptor(obj, ad) | descriptor ya da undefined | hayır |
Sık yapılan hatalar
- assign ile kopya sanmak:
Object.assign(a, b)yeni nesne üretmez,anesnesini değiştirir. - freeze ile derin dondurma beklemek: İç içe nesneler dondurulmaz; yukarıdaki
limit.gunlukörneğine bakın. - Anahtar sırasına güvenmek: MDN, düz nesnelerde özellik sırasının karmaşık kurallara bağlı olduğunu ve ona güvenmemenizi önerir. Ekleme sırası önemliyse Map kullanın.
- keys() sonucunda kalıtılan alanları aramak:
Object.keys()yalnızca nesnenin kendi alanlarını verir; prototipten gelenler için prototip ve kalıtım yazısına bakın.
Sık Sorulan Sorular
Object.keys ile for...in arasındaki fark nedir?
İkisi de numaralandırılabilir metin anahtarlarını aynı sırada verir. Fark şudur: for...in prototip zincirindeki numaralandırılabilir özellikleri de gezer, Object.keys() yalnızca nesnenin kendi özelliklerini döndürür.
Bir nesnede anahtar var mı diye nasıl bakarım?
Object.hasOwn(obj, "anahtar") nesnenin kendi özelliğini kontrol eder. "anahtar" in obj ise prototip zincirine de bakar. Değerin undefined olup olmadığına bakmak, değeri gerçekten undefined olan alanlarda yanıltıcıdır.
Object.freeze performans için mi kullanılır?
MDN bu metodu bir değişmezlik (immutability) aracı olarak anlatır; performansla ilgili bir iddia içermez. Sabit yapılandırmaları kazara değiştirilmekten korumak için kullanın.
Nesneyi derin kopyalamanın en kısa yolu nedir?
Object üzerinde yerleşik bir derin kopya metodu yoktur. Ortamda varsa structuredClone() kullanılır. JSON.parse(JSON.stringify(obj)) yöntemi tarih, undefined ve fonksiyon gibi değerleri bozar ya da kaybeder; nedenleri JSON.parse ve JSON.stringify yazısında.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: JavaScript öğrenme rehberi · Dizi metotları · Destructuring ve spread · Prototip ve kalıtım · JSON.parse ve JSON.stringify