if (nesnede anahtar) veya if (object.hasOwnProperty (anahtar)


173

Aşağıdaki iki ifade aynı çıktıyı üretiyor mu? Bir yolu diğerine tercih etmek için herhangi bir sebep var mı?

 if (key in object)

 if (object.hasOwnProperty(key))

Yanıtlar:


181

Dikkatli olun - aynı sonucu vermeyeceklerdir.

inAyrıca dönecektir trueeğer keybulundu bir yere alır prototip zincirinde ise, Object.hasOwnProperty(adı zaten bize söyler gibi), sadece dönecektir trueeğer keydoğrudan o nesne üzerinde kullanılabilir (onun mülkü "sahibi olan").


3
tam olarak ne demek istiyorsun in will also return true if key gets found somewhere in the prototype chain. bir örnek yazabilir misin Teşekkürler.
Lorraine Bernard

44
@Lor: ({foo:"bar"}).hasOwnProperty("toString")vs"toString" in ({foo:"bar"})
Ben Tembel Nefret

68

Başka bir örnekle açıklamaya çalışacağım. Diyelim ki iki özelliğe sahip aşağıdaki nesne var:

function TestObj(){
    this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';

TestObj örneğini oluşturalım:

var o = new TestObj();

Şimdi nesne örneğini inceleyelim:

console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true

console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true

Sonuç:

  • işleç, nesneye doğrudan veya prototipten erişilebiliyorsa her zaman true değerini döndürür

  • hasOwnProperty () yalnızca örnek üzerinde özellik varsa ancak prototipinde yoksa true değerini döndürür

Prototipte bazı özelliklerin varlığını kontrol etmek istiyorsak mantıklı olarak şunu söyleriz:

console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype

En sonunda:

Dolayısıyla, bu iki koşulun

if (key in object)
if (object.hasOwnProperty(key))

... aynı sonucu üretir, cevap açıktır, duruma göre değişir.



25

Özetle, hasOwnProperty()prototipiin bakmaktadır.

Alındığı O'Reilly Yüksek Performanslı Javascript :

Bir nesnenin hasOwnProperty () yöntemini kullanarak ve üyenin adını ileterek belirli bir ada sahip bir örnek üyesi olup olmadığını belirleyebilirsiniz. Bir nesnenin belirli bir ada sahip bir özelliğe erişimi olup olmadığını belirlemek için, in işlecini kullanabilirsiniz. Örneğin:

var book = {
    title: "High Performance JavaScript",
    publisher: "Yahoo! Press" 
};

alert(book.hasOwnProperty("title"));  //true
alert(book.hasOwnProperty("toString"));  //false
alert("title" in book); //true 
alert("toString" in book); //true

Bu kodda, başlık bir nesne örneği olduğu için “title” iletildiğinde hasOwnProperty () yöntemi true değerini döndürür; “toString” iletildiğinde yöntem örnekte bulunmadığından false değerini döndürür. Her özellik adı in işleciyle birlikte kullanıldığında, örnek ve prototipi araştırdığı için sonuç her iki kez de doğrudur.


5

Gerçekten harika cevaplar aldınız. Ben sadece bir nesne yineleme yaparken "hasOwnProperty" kontrol ihtiyacını kurtaracak bir şey sunmak istiyorum.

Bir nesne oluştururken genellikle insanlar onu bu şekilde oluşturacaktır:

const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }

Şimdi, "someMap" yoluyla yineleme yapmak istiyorsanız, bunu şu şekilde yapmanız gerekir:

const key
for(key in someMap ){
 if (someMap.hasOwnProperty(key)) { 
   // Do something
 }
}

Bunu, miras alınan mülkleri yinelemekten kaçınmak için yapıyoruz.

Yalnızca "harita" (yani anahtar / değer çiftleri) olarak kullanılacak basit bir nesne oluşturmak istiyorsanız, bunu şu şekilde yapabilirsiniz:

const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined

Şimdi böyle yinelemek güvenli olacak:

for(key in cleanMap){
 console.log(key + " -> " + newMap [key]);
 // No need to add extra checks, as the object will always be clean
}

Bu harika ipucunu burada öğrendim


1
daha ayrıntılı bir yazı: ryanmorr.com/true-hash-maps-in-javascript
darcher

2

Diğer form (içinde çağrılır) bir nesnenin özellik adlarını (veya anahtarlarını) numaralandırır. Her yinelemede, nesneye başka bir özellik adı dizesi değişkene atanır. Özellik adının gerçekten nesnenin bir üyesi olup olmadığını veya bunun yerine prototip zincirinde bulunup bulunmadığını belirlemek için object.hasOwnProperty (değişken) öğesini sınamak gerekir.

 for (myvar in obj) {
     if (obj.hasOwnProperty(myvar)) { ... } }

(Crockford'un Javascript'inden: İyi Parçalar )


5
inOperatör farklıdır for-inaçıklamada.
Tembel Nefret Ediyorum

Aslında ikisi de anahtar kelimede farklı kullanımlar
Jahan

4
Evet, inbir anahtar kelime. Ancak OP, inoperatör olarak özel kullanım hakkında sorular soruyor . Cevabınız for-inifadenin bir parçası olarak diğer kullanımla ilgilidir .
Tembel Nefret Ediyorum

-3

İlk sürüm daha kısadır (özellikle değişkenlerin yeniden adlandırıldığı küçültülmüş kodda)

a in b

vs

b.hasOwnProperty(a)

Her neyse, @AndreMeinhold'un dediği gibi, her zaman aynı sonucu vermezler.


1
Bu bir yorum olarak sahip olmak daha iyi olurdu. :-)
Hlawuleka MAS
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.