¿Hay alguna diferencia sustancial en hacer cualquiera de estos?
delete a.x;
vs
a.x = undefined;
dónde
a = {
x: 'boo'
};
¿se podría decir que son equivalentes?
(No estoy teniendo en cuenta cosas como "delete
Me gusta V8 no usar mejor" )
javascript
bevacqua
fuente
fuente
undefined
como el valor, que sigue siendo un ..Respuestas:
No son equivalentes. La principal diferencia es esa configuración
significa que
a.hasOwnProperty("x")
aún devolverá verdadero, y por lo tanto, todavía se mostrará en unfor in
bucle, y enObject.keys()
significa que
a.hasOwnProperty("x")
devolverá falsoLa forma en que son iguales es que no se puede saber si existe una propiedad mediante pruebas
Lo que no debe hacer si está tratando de determinar si existe una propiedad, siempre debe usar
Seguir la cadena de prototipos (mencionada por zzzzBov ) Llamar
delete
le permitirá subir la cadena de prototipos, mientras que establecer el valor en indefinido no buscará la propiedad en los prototipos encadenados http://jsfiddle.net/NEEw4/1/Eliminar propiedades heredadas Si la propiedad que está intentando eliminar es heredada,
delete
no la afectará. Es decir,delete
solo elimina propiedades del objeto en sí, no propiedades heredadas.Por lo tanto, si necesita asegurarse de que el valor de un objeto no esté definido,
delete
no funcionará cuando se herede la propiedad, tendrá que establecerlo (anularlo)undefined
en ese caso. A menos que se use el lugar que lo está comprobandohasOwnProperty
, pero probablemente no sería seguro suponer que en todas partes que lo verifique se usaráhasOwnProperty
fuente
"x" in a
También volverátrue
con el primero yfalse
con el segundo. La salida deObject.keys
también será diferente.undefined
, también puede verificarif (a.x)
, a menos que sea para números y 0 sea válidoParafraseando la pregunta:
No.
El primero elimina la clave de la variable, el segundo establece la clave con un valor de
undefined
. Esto marca la diferencia cuando se itera sobre las propiedades de los objetos y cuandohasOwnProperty
se usa.Además, esto hará una diferencia significativa cuando la cadena de prototipos esté involucrada.
fuente
delete
permitirle subir a la cadena de prototiposSi
a.x
es una función de establecimiento,a.x = undefined
llamará a la función mientrasdelete a.x
que no la llamará.fuente
Sí, hay una diferencia. Si usa
delete a.x
la x ya no es una propiedad de a, pero si la usaa.x=undefined
es una propiedad pero su valor no está definido.fuente
Los nombres son un poco confusos.
a.x = undefined
solo establece la propiedad enundefined
, pero la propiedad sigue ahí:delete
en realidad lo elimina:fuente
Este REPL del nodo debería ilustrar la diferencia.
fuente
Estoy seguro de que puedes ver la diferencia entre
var o1 = {p:undefined};
yvar o2 = {};
.En ambos casos,
o.p
será ,undefined
pero en el primer caso, es porque ese es el valor y en el segundo caso porque no hay valor .delete
es el operador que le permite obtener a partir deo1
(u otro objeto que tiene un valor asignado a sup
propiedad) parao2
de esa manera:delete o1.p;
.La operación inversa se realiza simplemente asignando un valor (
undefined
en este ejemplo, pero podría ser otra cosa) a la propiedado1.p = undefined;
.Entonces no , no son equivalentes.
delete o.p;
seráeliminar la propiedad
p
del objeto si tiene unono hacer nada de otra manera
o.p = undefined;
seráagregue una propiedad
p
al objeto si aún no tiene una y establezca su valor enundefined
simplemente cambie el valor de la propiedad si el objeto ya lo tiene
Desde una perspectiva de rendimiento,
delete
es malo porque modifica la estructura del objeto (al igual que agregar una nueva propiedad si no lo ha inicializado en el constructor).Mientras que establecer el valor para
undefined
liberar el contenido también, pero sin obligar a modificar la estructura.fuente
El objeto es simplemente una representación en árbol, es decir, en la memoria, la raíz apunta a varias ubicaciones de memoria donde se almacenan las claves de ese objeto. y esa ubicación apunta a otra ubicación donde se almacena el valor real de esa clave, o ubicaciones donde se almacenan las claves secundarias o ubicaciones donde se almacenan los valores de la matriz.
Cuando elimina cualquier clave de un objeto usando delete, en realidad elimina el enlace entre esa clave y su objeto principal y las ubicaciones de memoria de la clave y su valor se liberan para almacenar otra información.
Cuando intenta eliminar cualquier clave configurando undefined como su valor, simplemente está configurando su valor, no eliminando esa clave. Eso significa que la ubicación de la memoria de claves todavía está vinculada con su objeto principal y el valor si la clave no está definida.
Usar una palabra clave indefinida en lugar de eliminar es una mala práctica, ya que no libera la ubicación de memoria de esa clave.
Incluso si la clave no está presente, y la configura como indefinida, esa clave se creará con valor
undefined
.p.ej
eliminar no se puede trabajar con propiedades heredadas porque esa propiedad no es parte de ese objeto secundario.
fuente
as a general rule of thumb, using 'delete' makes thing slower.
y 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.
, y finalmente smashingmagazine.com/2012/11/…Usando una matriz, en lugar de un objeto, puedo mostrar que eliminar usa menos memoria de almacenamiento dinámico que indefinido.
Por ejemplo, este código no terminará:
Produce este error:
Entonces, como puede ver, en
undefined
realidad ocupa memoria de montón.Sin embargo, si también
delete
utiliza el elemento ary (en lugar de simplemente configurarloundefined
), el código terminará lentamente:Estos son ejemplos extremos, pero señalan
delete
que no he visto a nadie mencionar en ningún lado.fuente