javascript - Object.create(null) ile JS nesnesi oluşturmak {} ile aynı mı?


JS nesneleri oluşturmanın birçok yolunu biliyorum ama Object.create(null)'unkiyi bilmiyordum.

Soru:

tam olarak aynı mı:

var p = {}

karşı

var p2 = Object.create(null);

?

Cevap #1

Onlar eşdeğer değildir. {}.constructor.prototype === Object.prototype iken Object.create(null) hiçbir şeyden miras almaz ve bu nedenle hiç özelliği yoktur.

Başka bir deyişle: Bir JavaScript nesnesi, açıkça null ile prototipini oluşturmadığınız sürece varsayılan olarak Object'ten miras alır, örneğin: Object.create(null).

{}, bunun yerine Object.create(Object.prototype) ile eşdeğer olur.


Chrome Geliştirici Araçlarında Object.create(null) öğesinin prototipi olmadığını, oysa {} öğesinin prototipi olduğunu görebilirsiniz.

Cevap #2

Kesinlikle eşdeğer değiller. Bu cevabı, neden bir fark yarattığını daha ayrıntılı açıklamak için yazıyorum.

  1. var p = {};

    Object'ten özellikleri ve yöntemleri miras alan bir nesne oluşturur.

  2. var p2 = Object.create(null);

    Hiçbir şey miras almayan bir nesne oluşturur.

Eğer bir nesneyi harita olarak kullanıyorsanız ve yukarıdaki yöntem 1 ile bir nesne oluşturduysanız, haritada arama yaparken ekstra dikkatli olmalısınız. Çünkü Object’ten gelen özellikler ve yöntemler devralındığından, kodunuz haritada asla eklemediğiniz anahtarların olduğu bir durumla karşılaşabilir. Örneğin, toString üzerinde bir arama yaparsanız, o değeri hiç eklememiş olmanıza rağmen bir fonksiyon bulursunuz. Bunu şu şekilde aşabilirsiniz:

if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
    // we actually inserted a 'toString' key into p
}

Bir şeyi p.toString'e atamanın sorun olmadığını unutmayın, bu sadece p'deki miras alınmış toString fonksiyonunu geçersiz kılacaktır.

Şunu unutmayın: Sadece p.hasOwnProperty('toString') yapamazsınız çünkü p'ye bir "hasOwnProperty" anahtarı eklemiş olabilirsiniz, bu yüzden Object.prototype'daki uygulamayı kullanmasını zorunlu kılıyoruz.

Öte yandan, yukarıdaki 2. yöntemi kullanırsanız, o zaman Object öğelerinin haritada görünmesi konusunda endişelenmenize gerek kalmaz.

Bir özelliğin varlığını bu şekilde basit bir if ile kontrol edemezsiniz:

// Unreliable:
if (p[someKey]) {
    // ...
}

Değer boş bir dize, false, null, undefined, 0 veya NaN vb. olabilir. Bir özelliğin tamamen var olup olmadığını kontrol etmek için hâlâ Object.prototype.hasOwnProperty.call(p, someKey) kullanmanız gerekecektir.

İlgili makaleler