objetos - prototype javascript ejemplos
¿Cómo listar las propiedades de un objeto JavaScript? (16)
Digamos que creo un objeto así:
var myObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
¿Cuál es la mejor manera de recuperar una lista de los nombres de propiedades? es decir, me gustaría terminar con algunas ''claves'' variables tales que:
keys == ["ircEvent", "method", "regex"]
A partir de la respuesta aceptada.
Si el objeto tiene propiedades a las que desea llamar, diga .properties () ¡inténtelo!
var keys = Object.keys(myJSONObject);
for (var j=0; j < keys.length; j++) {
Object[keys[j]].properties();
}
Bajo los navegadores que soportan js 1.8:
[i for(i in obj)]
Como respondió Sam Dutton, se ha introducido un nuevo método para este propósito en ECMAScript 5th Edition. Object.keys()
hará lo que quieras y es compatible con Object.keys , Chrome 6, Safari 5 e IE 9 .
También puede implementar fácilmente el método en navegadores que no lo admiten. Sin embargo, algunas de las implementaciones no son totalmente compatibles con Internet Explorer. He detallado esto en mi blog y he producido una solución más compatible:
Object.keys = Object.keys || (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
DontEnums = [
''toString'', ''toLocaleString'', ''valueOf'', ''hasOwnProperty'',
''isPrototypeOf'', ''propertyIsEnumerable'', ''constructor''
],
DontEnumsLength = DontEnums.length;
return function (o) {
if (typeof o != "object" && typeof o != "function" || o === null)
throw new TypeError("Object.keys called on a non-object");
var result = [];
for (var name in o) {
if (hasOwnProperty.call(o, name))
result.push(name);
}
if (hasDontEnumBug) {
for (var i = 0; i < DontEnumsLength; i++) {
if (hasOwnProperty.call(o, DontEnums[i]))
result.push(DontEnums[i]);
}
}
return result;
};
})();
Tenga en cuenta que la respuesta actualmente aceptada no incluye una comprobación de hasOwnProperty () y devolverá las propiedades que se heredan a través de la cadena de prototipos. Tampoco tiene en cuenta el famoso error DontEnum en Internet Explorer donde las propiedades no enumerables en la cadena del prototipo hacen que las propiedades declaradas localmente con el mismo nombre hereden su atributo DontEnum.
Implementar Object.keys () te dará una solución más robusta.
EDITAR: luego de una discusión reciente con kangax , un conocido colaborador de Prototype, implementé la solución para el error DontEnum basado en el código de su función Object.forIn()
que se encuentra here .
Como señaló slashnick , puede usar la construcción "for in" para iterar sobre un objeto para sus nombres de atributos. Sin embargo, estará iterando sobre todos los nombres de atributo en la cadena de prototipo del objeto. Si desea iterar solo sobre los atributos propios del objeto, puede hacer uso del método Object#hasOwnProperty() . Teniendo así lo siguiente.
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
/* useful code here */
}
}
En los navegadores modernos (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) puede usar el método Object.keys :
var keys = Object.keys(myObject);
Lo anterior tiene un polyfill completo pero una versión simplificada es:
var getKeys = function(obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
Alternativamente, reemplace var getKeys
con Object.prototype.keys
para permitirle llamar a .keys()
en cualquier objeto. Extender el prototipo tiene algunos efectos secundarios y no recomendaría hacerlo.
Esto funcionará en la mayoría de los navegadores, incluso en IE8, y no se requieren bibliotecas de ningún tipo. var i es tu llave
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);
IE no admite para (i en obj) para propiedades nativas. Aquí hay una lista de todos los accesorios que pude encontrar.
Parece que hace un filtrado estúpido.
La lista está disponible en la parte inferior de esta publicación de grupo de Google: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0
La solución funciona en mis casos y cross-browser:
var getKeys = function(obj) {
var type = typeof obj;
var isObjectType = type === ''function'' || type === ''object'' || !!obj;
// 1
if(isObjectType) {
return Object.keys(obj);
}
// 2
var keys = [];
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
keys.push(i)
}
}
if(keys.length) {
return keys;
}
// 3 - bug for ie9 <
var hasEnumbug = !{toString: null}.propertyIsEnumerable(''toString'');
if(hasEnumbug) {
var nonEnumerableProps = [''valueOf'', ''isPrototypeOf'', ''toString'',
''propertyIsEnumerable'', ''hasOwnProperty'', ''toLocaleString''];
var nonEnumIdx = nonEnumerableProps.length;
while (nonEnumIdx--) {
var prop = nonEnumerableProps[nonEnumIdx];
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
keys.push(prop);
}
}
}
return keys;
};
Mozilla tiene todos los detalles de implementación sobre cómo hacerlo en un navegador donde no es compatible, si eso ayuda:
if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable(''toString''),
dontEnums = [
''toString'',
''toLocaleString'',
''valueOf'',
''hasOwnProperty'',
''isPrototypeOf'',
''propertyIsEnumerable'',
''constructor''
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== ''object'' && typeof obj !== ''function'' || obj === null) throw new TypeError(''Object.keys called on non-object'');
var result = [];
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) result.push(prop);
}
if (hasDontEnumBug) {
for (var i=0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
}
}
return result;
};
})();
}
Puede incluirlo como desee, pero posiblemente en algún tipo de archivo extensions.js
en la parte superior de su pila de scripts.
Podría hacerlo con jQuery de la siguiente manera:
var objectKeys = $.map(object, function(value, key) {
return key;
});
Si está intentando obtener solo los elementos pero no las funciones, este código puede ayudarlo.
this.getKeys = function() {
var keys = new Array();
for(var key in this) {
if( typeof this[key] !== ''function'') {
keys.push(key);
}
}
return keys;
}
esto es parte de mi implementación del HashMap y solo quiero las claves, "este" es el objeto hashmap que contiene las claves
Soy un gran fan de la función de volcado.
http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion
Tenga en cuenta que Object.keys y otros métodos de ECMAScript 5 son compatibles con Firefox 4, Chrome 6, Safari 5, IE 9 y superior.
Por ejemplo:
var o = {"foo": 1, "bar": 2};
alert(Object.keys(o));
Tabla de compatibilidad de ECMAScript 5: kangax.github.com/es5-compat-table
Descripción de los nuevos métodos: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/
Utilice Reflect.ownKeys()
var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]
Object.keys y Object.getOwnPropertyNames no pueden obtener propiedades no enumerables . Está funcionando incluso para propiedades no enumerables .
var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
Ya que uso underscore.js en casi todos los proyectos, usaría la función de las keys
:
var obj = {name: ''gach'', hello: ''world''};
console.log(_.keys(obj));
La salida de eso será:
[''name'', ''hello'']
Object.getOwnPropertyNames(obj)
Esta función también muestra propiedades no enumerables además de las que muestra Object.keys(obj)
.
En JS, cada propiedad tiene algunas propiedades, incluido un enumerable
booleano.
En general, las propiedades no enumerables son más "internas" y se usan con menos frecuencia, pero es perspicaz mirarlas a veces para ver qué está sucediendo realmente.
Ejemplo:
var o = Object.create({base:0})
Object.defineProperty(o, ''yes'', {enumerable: true})
Object.defineProperty(o, ''not'', {enumerable: false})
console.log(Object.getOwnPropertyNames(o))
// [ ''yes'', ''not'' ]
console.log(Object.keys(o))
// [ ''yes'' ]
for (var x in o)
console.log(x)
// yes, base
También tenga en cuenta cómo:
-
Object.getOwnPropertyNames
yObject.keys
no suben la cadena del prototipo para encontrar labase
-
for in
hace
Más sobre la cadena de prototipos aquí: https://.com/a/23877420/895245