2015-08-12 21 views
6

Zaleca się, aby zawsze używać hasOwnProperty, ale w wielu przypadkach nie jest to konieczne. Na przykład rozważmy następujący kod:hasOwnProperty kiedy używać, a kiedy nie jest potrzebne?

var object = JSON.parse(somejsontext); 
for(var prop in object) { 
    console.log(object[prop]); 
} 

wiem, że w tym przypadku prop stanowi część obiektu, jest explict definiować przez for..in.

Ale według MOZ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty powinniśmy używać go w celu uniknięcia Iterowanie nad non-enumarable rekwizytów, z tego przykładu:

var buz = { 
    fog: 'stack' 
}; 

for (var name in buz) { 
    if (buz.hasOwnProperty(name)) { 
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]); 
    } 
    else { 
    console.log(name); // toString or something else 
    } 
} 

Ale testowania tego kodu rzeczywiście, nigdy nie idzie do innego.

Kiedy zatem ma sens zastosowanie hasOwnProperty?

UPDATE: Biorąc pod uwagę odpowiedź wybrany poniżej, możemy safetly unikać stosowania hasOwnProperty w tych przypadkach: - Object js nie została rozszerzona o dowolnej biblioteki javascript lub przez naszego kodu - Object jest prosty kod, który mamy kontrolę pod numerem

+0

http://stackoverflow.com/questions/13632999/if-key-in-object-or-ifobject-hasownpropertykey – Andreas

Odpowiedz

7

Problem pojawia się, gdy prototyp zawiera wyliczalne właściwości, których twój kod nie przewidział. Na przykład, załóżmy, że ten biegł tuż przed swoim przykładzie:

Object.prototype.foobar = "hello"; 

W tym przypadku iteracji nad buz obejmowałyby enumerable własność foobar prototypu. Ten wzór hasOwnProperty umożliwia kodowi rozróżnienie między właściwościami, które są bezpośrednio na obiekcie w porównaniu do właściwości, które są dziedziczone po prototypowym przodku.

Problem nie polega na "wyliczaniu wartości na nieprzeliczalnych właściwościach" (to z definicji niemożliwe, chyba że wyraźnie uzyskasz je przez getOwnPropertyNames dla każdego poziomu hierarchii prototypów), ale wyliczanie na podstawie dziedziczonych właściwości. Jest to problemem, gdy korzystamy z bibliotek, które mogą dodawać właściwości przeliczalne do prototypów wysokiego poziomu, dokładnie tak, jak to zilustrowałem powyżej.

Jeśli chcesz dodać obiekt do prototypu bez powodowania, że ​​nieruchomość być wyliczone, można zrobić bez przeliczalny nieruchomość z Object.defineProperty:

Object.defineProperty(Object.prototype, "foobar", { 
    value: "hello", 
    enumerable: false, 
    writeable: true, 
    configurable: true 
}); 

Taka właściwość będzie nie pojawić się w for..in pętla na buz (lub w pętli for..in bezpośrednio na Object.prototype, albo).

+0

tak, ale nie miałoby sensu, gdy masz kontrolę nad twoim kodem, (mając nadzieję, że biblioteka nie przedłużać prototypu podstawowego obiektu) – albanx

+0

@albanx Wiele bibliotek znacznie rozszerza rodzime obiekty, nawet 'Object.prototype' może być rozszerzony. – Teemu

+0

Ale w mozilli przykład dlaczego nie czyta się za pomocą metody toString. . – albanx

Powiązane problemy