tag - Diferencia entre indefinido y no definido en Javascript.
title of page html (2)
Ambos, el acceso a una propiedad que no está definida en un objeto y una propiedad que contiene el valor undefined
primitivo, lo devolverá undefined
.
Por ejemplo:
var obj = {
a: undefined
};
obj.a; // undefined
obj.b; // undefined
La diferencia es que a
es una propiedad propia, y b
no es:
obj.hasOwnProperty(''a''); // true
obj.hasOwnProperty(''b''); // false
En el primer caso, a
es una propiedad propia, incluso si contiene undefined
valor undefined
. En el segundo caso, b
no es una propiedad propia, accediendo a obj.b
buscará una propiedad llamada b
, en la cadena del prototipo.
Cuando la cadena del prototipo finaliza (cuando llega a un objeto con un [[Prototype]]
null
), la búsqueda de propiedades finaliza y la undefined
se devuelve explícitamente.
Debe saber que el método hasOwnProperty
solo verifica si la propiedad existe físicamente en el objeto (propiedades propias ), pero también hemos heredado propiedades, para ese caso podemos usar el operador in
, por ejemplo:
function Test () {}
Test.prototype.a = ''foo''; // instances of Test will inherit from Test.prototype
var obj = new Test(); // { a="foo", b="bar"}
obj.b = ''bar'';
obj.hasOwnProperty(''a''); // false
''a'' in obj; // true
obj.a; // ''foo''
obj.hasOwnProperty(''b''); // true
Como puede ver, obj
hereda de Test.prototype
, y a
propiedad no es una propiedad propia , pero está disponible a través de la cadena de prototipos. Es por eso que hasOwnProperty
devuelve false
y el operador in
devuelve true
.
Puede ver cómo se resuelven internamente las propiedades mediante la operación interna hasOwnProperty
Notas:
- El acceso
undefined
como un identificador no se considera seguro en ECMAScript 3 (la versión más implementada del estándar de idioma), porque en lugar de ser una palabra clave de idioma (comonull
por ejemplo) es solo una propiedad del objeto global, y se puede escribir en esta versión de la especificación, lo que significa que si alguien reemplaza su valor (por ejemplo,window.undefined = ''LOL'';
), romperá su código.
En su lugar, se puede usar el operador typeof
como menciones @strager, por ejemplo:
if (typeof obj.prop == ''undefined'') { /*....*/ }
Este operador siempre devuelve una cadena (es seguro usar ==
:), y su valor depende del tipo de su operando, los valores posibles se describen here .
Otra forma común de resolver esto es declarar su propia variable undefined
, disponible en el ámbito de sus funciones, por ejemplo, algunas bibliotecas usan el siguiente patrón:
(function(undefined) {
// code here
})();
La función tiene un argumento llamado undefined
, y se ejecuta inmediatamente sin pasarle ningún valor (el último par o parens hacen la invocación).
Quizás vale la pena mencionar que la propiedad global undefined
finalmente se describió en ECMAScript 5 como no escribible (inmutable, así como no enumerable y no configurable -no eliminable-).
El uso del método
hasOwnProperty
directamente desde una instancia de objeto tampoco se considera seguro , ya que si algún objeto tiene una propiedad con el mismo nombre, el método original quedará sombreado. Por ejemplo:var obj = { hasOwnProperty: function () { /* evil code :) */ } };
Si llamas:
obj.hasOwnProperty(''prop'');
El método definido en el objeto se ejecutará (y no querrá esto, ya que sabe exactamente qué método desea invocar ...), porque Object.prototype
el Object.prototype
del Object.prototype
, sin embargo, puede ser invocado de forma segura por :
Object.prototype.hasOwnProperty.call(obj, ''prop'');
Consulte http://jsfiddle.net/FDhQF/1/ para ver un ejemplo trivial.
¿Cuál es la diferencia entre que algo no esté definido y algo que no esté definido en Javascript? Por ejemplo, intentar acceder a una propiedad para un objeto (de hecho, intentar acceder a una variable) que no está definida devolverá undefined
. Pero también puedes establecer algo = undefined
. Cuando haces eso, tratar de acceder a él todavía vuelve indefinido, pero el puntero sigue ahí. Un ejemplo, como el de arriba, es cómo la iteración sobre un objeto aún pasa por la propiedad que usted (re) declaró como no definido. Parece que hay dos tipos diferentes de indefinidos. ¿Alguien puede arrojar algo de luz sobre la situación?
Here hay una buena explicación de "indefinido". Sin embargo, lo esencial es que establecer algo como "indefinido" no lo define UN, porque "indefinido" es en realidad un valor primitivo, que se usa cuando a una variable (o propiedad) no se le ha asignado un valor.