2012-10-04 16 views
51

Powiel możliwe:
How do I check to see if an object has a property in Javascript?for..in i hasOwnProperty

znalazłem następujący fragment kodu w plikach JS Twittera. Zastanawiam się, dlaczego muszą wywołać funkcję hasOwnProperty, aby zobaczyć, że "dict" ma właściwość "kluczową"? Pętla for działa dla każdego "klucza" w "dict", co oznacza, że ​​"dict" ma "klucz". Czy brakuje mi punktu?

function forEach(dict, f) { 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) 
      f(key, dict[key]); 
    } 
} 
+3

Jest to dobrze wyjaśnione tutaj: http://stackoverflow.com/a/136411/27512 – kevingessner

+0

Wygląda na to, że 'klucz' jest globalny, skąd pochodzi ten kod, czy możesz umieścić w nim link? – elclanrs

+0

@elclanrs Myliłem się. Ten kod pochodzi z Chrome utils.js – scusyxx

Odpowiedz

54

Bo jeśli nie, to będzie pętli każdego obiektu w łańcuchu prototypów, w tym te, które nie wiedzą o (które były prawdopodobnie dodane przez kogoś brudząc z natywnych prototypów obiektu).

W ten sposób gwarantujemy tylko klucze znajdujące się w tej instancji obiektu.

+0

Wielkie dzięki. Teraz ma więcej sensu .. – scusyxx

5

Każdy obiekt na javascript jest słownikiem, oznacza to, że „toString” i każda inna metoda jest kluczowym każdego obiektu

var myObj = {}; 
console.log(myObj["toString"]); 

Jednak funkcja ta jest dziedziczona z klasy Object, więc hasOwnProperty informuje, czy to klucz jest własnością słownika lub jest dziedziczony.

"toString" in myObj; // true 
myObj.hasOwnProperty("toString") // false 
1

@blockhead jest tutaj. Na przykład framework Prototype.js używany do rozszerzania rodzimych macierzy z dodatkowymi metodami pomocniczymi (nie znam sytuacji z aktualnymi wersjami frameworka). W ten sposób proste użycie "for (key in dict)" zwróci wszystkie elementy div oraz odwołania do metod pomocniczych. Co jest nieoczekiwane :)

26

Metoda hasOwnProperty informuje, czy właściwość znajduje się bezpośrednio na instancji obiektu, czy odziedziczona po prototypowym łańcuchu.

Rozważmy następujący

function ObjWithProto() { 
    this.foo = 'foo_val'; 
} 

ObjWithProto.prototype = {bar: 'bar_val'}; 

var dict = new ObjWithProto(); 
dict.foobar = 'foobar_val'; 

tj użytkownik posiada Objectdict o właściwościach foo i foobar że również dziedziczy nieruchomość bar od jego łańcucha prototypów.

Teraz uruchom go poprzez (zmodyfikowanej wersji) swój kod

function forEach(dict) { 
    var key; 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) console.log('has', key, dict[key]); 
     else console.log('not', key, dict[key]); 
    } 
} 
forEach(dict); 

Zobaczysz

has foo foo_val 
has foobar foobar_val 
not bar bar_val 

Pozwala to odrębne właściwości, że obiekt ma się i tych, których odziedziczyła (co zwykle są to metody, które nie mają związku z pętlą)

Ponadto, jeśli teraz robisz dict.bar = 'new_bar_val';, ostatni wynik zmieni się na has bar new_bar_val, umożliwiając rozróżnienie między właściwościami o tej samej nazwie co odziedziczone.

Powiązane problemy