
brady
Quiero definir métodos auxiliares en Array.prototype y Object.prototype. Mi plan actual es hacer algo como:
Array.prototype.find = function(testFun) {
// code to find element in array
};
Para que pueda hacer esto:
var arr = [1, 2, 3];
var found = arr.find(function(el) { return el > 2; });
Funciona bien, pero si recorro la matriz en un for in
loop los métodos aparecen como valores:
for (var prop in arr) { console.log(prop); }
// prints out:
// 1
// 2
// 3
// find
Esto arruinará a cualquiera que confíe en el for in
para mostrar valores (especialmente en Objetos). Las versiones posteriores de javascript tienen funciones .map y .filter integradas en matrices, pero esas no aparecen en for in
bucles ¿Cómo puedo crear más métodos como ese que no aparecerán en un for in
¿lazo?

Bergi
Es bastante fácil: no use bucles for-in con Arrays. Culpe a todos los demás que lo hacen: aquí hay un buen fragmento para contarles durante el desarrollo.
Por supuesto, si uno hace una enumeración en una función genérica y no sabe si obtiene una matriz, un objeto simple o un objeto con un prototipo personalizado, puede usar hasOwnProperty
Me gusta esto:
for (var prop in anyObj )
if (Object.prototype.hasOwnProperty.call(anyObj, prop))
// do something
Nótese el uso explícito de Object.prototype
para obtener la función: puede haber objetos que lo sobrescriban (especialmente en los mapas de datos, el valor podría ni siquiera ser una función), objetos que no lo admiten u objetos que no heredan de Object.prototype en absoluto. Ver también aquí.
Sin embargo, solo un autor de secuencias de comandos que es consciente del problema filtraría todos sus bucles for-in, y algunos solo lo hacen porque se recomienda, y lo hace en su mayoría mal, debería haber usado una iteración de matriz for-loop en su lugar. Pero nuestro problema son aquellos autores que no lo saben.
Un enfoque interesante, pero exclusivo de Mozilla, sería sobrescribir el comportamiento de las enumeraciones en matrices a través de __iterate__
como se demuestra aquí.
Afortunadamente, EcmaScript 5.1 nos permite establecer propiedades para ser no enumerable. Por supuesto, esto no es compatible con los navegadores más antiguos, pero ¿por qué molestarse? Necesitaríamos usar es5-shims de todos modos, para todas las cosas geniales de matriz de orden superior 🙂 defineProperty
Me gusta esto:
Object.defineProperty(Array.prototype, "find", {
enumerable: false,
writable: true,
value: function(testFun) {
// code to find element in array
}
});
Dependiendo de sus restricciones:
// In EcmaScript 5 specs and browsers that support it you can use the Object.defineProperty
// to make it not enumerable set the enumerable property to false
Object.defineProperty(Array.prototype, 'find', {
enumerable: false, // this will make it not iterable
get: function(testFun) {
// code to find element in array
};
});
Leer más sobre Objeto.defineProperty aquí https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
Es porque hay que buscar hasOwnProperty
:
for (var prop in arr) {
if (arr.hasOwnProperty(prop)) {
console.log(prop)
}
}
Ahora esto registra 1, 2, 3.
Las respuestas anteriores pierden un punto:
enumerable… Predeterminado a falso. (mdn)
Así que simplemente usando Object.defineProperty(Array.prototype, 'myFunc' myFunc)
en lugar de Array.prototype.myFunc = myFunc
resolverá el problema.
Esa es solo la razón de no usar bucles for-in en matrices!
– Bergi
8 de noviembre de 2012 a las 19:38
No modifique objetos que no le pertenecen.
– Matemáticas
8 de noviembre de 2012 a las 19:42