Czy jest jakaś istotna różnica w wykonaniu któregokolwiek z tych działań?
delete a.x;
vs
a.x = undefined;
gdzie
a = {
x: 'boo'
};
czy można powiedzieć, że są równoważne?
(Nie biorę pod uwagę rzeczy typu „V8 lubi nie używać delete
lepiej” )
javascript
bevacqua
źródło
źródło
undefined
jako wartość, która nadal jest ..Odpowiedzi:
Nie są równoważne. Główną różnicą jest to ustawienie
oznacza, że
a.hasOwnProperty("x")
nadal będzie zwracać wartość true, a zatem nadal będzie pojawiać się wfor in
pętli i w formacieObject.keys()
oznacza, że
a.hasOwnProperty("x")
zwróci fałszSposób, w jaki są takie same, polega na tym, że nie można stwierdzić, czy właściwość istnieje, testując
Czego nie powinieneś robić, jeśli próbujesz ustalić, czy właściwość istnieje, zawsze powinieneś jej używać
Podążanie za łańcuchem prototypów (wspomnianym przez zzzzBov ) Wywołanie
delete
pozwoli mu przejść w górę łańcucha prototypów, podczas gdy ustawienie wartości na undefined nie spowoduje wyszukania właściwości w połączonych prototypach http://jsfiddle.net/NEEw4/1/Usuwanie odziedziczonych właściwości Jeśli właściwość, którą próbujesz usunąć, jest dziedziczona,
delete
nie ma na nią wpływu. Oznacza to,delete
że usuwa tylko właściwości z samego obiektu, a nie właściwości dziedziczone.Dlatego jeśli chcesz się upewnić, że wartość obiektu będzie niezdefiniowana,
delete
nie zadziała, gdy właściwość zostanie odziedziczona, będziesz musiałundefined
w takim przypadku ustawić (nadpisać) ją na . Chyba że miejsce, które go sprawdza, będzie używaćhasOwnProperty
, ale prawdopodobnie nie byłoby bezpiecznie założyć, że wszędzie, gdzie sprawdza, będzie używaćhasOwnProperty
źródło
"x" in a
powróci takżetrue
z pierwszym ifalse
drugim. WynikObject.keys
będzie również inny.undefined
, możesz równie dobrze po prostu sprawdzićif (a.x)
, chyba że jest to dla liczb i 0 jest poprawneParafrazując pytanie:
Nie.
Pierwsza usuwa klucz ze zmiennej, później ustawia klucz na wartość
undefined
. Ma to znaczenie podczas iteracji po właściwościach obiektów i kiedyhasOwnProperty
jest używany.Ponadto spowoduje to znaczącą różnicę, gdy w grę wchodzi łańcuch prototypów.
źródło
delete
dopuszczenia go w górę łańcucha prototypówJeśli
a.x
jest funkcją ustawiającą,a.x = undefined
wywoła funkcjędelete a.x
, ale nie wywoła funkcji.źródło
Tak, jest różnica. Jeśli użyjesz
delete a.x
x, nie jest już właściwością a, ale jeśli używasza.x=undefined
go, jest to właściwość, ale jej wartość jest niezdefiniowana.źródło
Nazwy są trochę zagmatwane.
a.x = undefined
po prostu ustawia właściwość naundefined
, ale właściwość nadal istnieje:delete
faktycznie usuwa to:źródło
Ta REPL z węzła powinna zilustrować różnicę.
źródło
Jestem pewien, że widzisz różnicę między
var o1 = {p:undefined};
ivar o2 = {};
.W obu przypadkach
o.p
będzie,undefined
ale w pierwszym przypadku to dlatego, że jest to wartość, aw drugim, ponieważ nie ma wartości .delete
jest operatorem, który pozwala dostać się zo1
(lub inny obiekt, który ma przypisaną wartość jegop
majątku) nao2
tej drodze:delete o1.p;
.Operacja odwrotna polega po prostu na przypisaniu wartości (
undefined
w tym przykładzie, ale może to być coś innego) do właściwościo1.p = undefined;
.Więc nie , nie są one równoważne.
delete o.p;
będzieusunąć właściwość
p
z obiektu, jeśli taki posiadanic innego nie rób
o.p = undefined;
będziedodaj właściwość
p
do obiektu, jeśli jeszcze jej nie ma, i ustaw jej wartość naundefined
po prostu zmień wartość właściwości, jeśli obiekt już ją posiada
Z punktu widzenia wydajności
delete
jest zły, ponieważ modyfikuje strukturę obiektu (podobnie jak dodanie nowej właściwości, jeśli nie zainicjowałeś jej w konstruktorze).Natomiast ustawienie wartości na
undefined
zwalnia również zawartość, ale bez wymuszania modyfikacji struktury.źródło
Obiekt jest po prostu reprezentacją drzewa, co oznacza, że w pamięci korzeń wskazuje różne miejsca w pamięci, w których przechowywane są klucze tego obiektu. a ta lokalizacja wskazuje na inną lokalizację, w której przechowywana jest rzeczywista wartość tego klucza, lub lokalizacje, w których przechowywane są klucze potomne, lub lokalizacje, w których przechowywane są wartości tablicowe.
Kiedy usuwasz dowolny klucz z obiektu za pomocą funkcji delete, w rzeczywistości usuwa on łącze między tym kluczem a jego obiektem nadrzędnym, a lokalizacje klucza i jego wartość są zwalniane do przechowywania innych informacji.
Kiedy próbujesz usunąć dowolny klucz, ustawiając wartość undefined jako jego wartość, po prostu ustawiasz jego wartość, a nie usuwasz tego klucza. Oznacza to, że lokalizacja pamięci kluczy jest nadal połączona z obiektem nadrzędnym i wartością, jeśli klucz jest niezdefiniowany.
Używanie undefined zamiast używania słowa kluczowego delete jest złą praktyką, ponieważ nie zwalnia lokalizacji pamięci tego klucza.
Nawet jeśli klucz nie istnieje i ustawisz go jako niezdefiniowany, ten klucz zostanie utworzony z wartością
undefined
.na przykład
nie można pracować z właściwościami dziedziczonymi, ponieważ ta właściwość nie jest częścią tego obiektu podrzędnego.
źródło
as a general rule of thumb, using 'delete' makes thing slower.
i developers.google.com/v8/designTo reduce the time required to access JavaScript properties, V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes. In V8, an object changes its hidden class when a new property is added.
i wreszcie smashingmagazine.com/2012/11/ ...Używając tablicy zamiast obiektu, mogę pokazać, że funkcja delete zużywa mniej pamięci sterty niż wartość undefined.
Na przykład ten kod nie zakończy się:
Generuje ten błąd:
Tak więc, jak widać,
undefined
faktycznie zajmuje pamięć sterty.Jednakże, jeśli również wybierzesz
delete
element ary (zamiast po prostu ustawić go naundefined
), kod powoli się zakończy:To są skrajne przykłady, ale wskazują na
delete
to, że nie widziałem nikogo o czym wspominał.źródło