En javascript defino una matriz como esta
var arr = [1,2,3];
también puedo hacer
arr[-1] = 4;
Ahora si lo hago
arr = undefined;
También pierdo la referencia al valor en arr [-1] .
Entonces, para mí, lógicamente, parece que arr [-1] también es parte de arr .
Pero cuando sigo (sin establecer arr en indefinido)
arr.length;
Devuelve 3, no 4 ;
Entonces, mi punto es que si las matrices se pueden usar con índices negativos, estos índices negativos también deberían ser parte de su longitud **. No sé, puede que me equivoque o que me falte algún concepto sobre las matrices.
javascript
arrays
me_digvijay
fuente
fuente
arr[1.5] = 1
y eso tampoco afecta la longitud. La especificación del lenguaje es muy clara sobre lo que afecta la longitud. Puede que no te guste, pero tienes que vivir con ello. O eso o diseña tu propio lenguaje competitivo y convence a la gente para que lo cambie.var a = []; a['foo'] = 'baz'
pero eso no significa que deba hacerlo; está claramente en contra de todas las convenciones.Respuestas:
Sí, lo es, pero no de la manera que usted cree.
Puede asignar propiedades arbitrarias a una matriz (como cualquier otro Objeto en JavaScript), que es lo que está haciendo cuando "indexa" la matriz
-1
y asigna un valor. Dado que este no es un miembro de la matriz y solo una propiedad arbitraria, no debe esperarlength
considerar esa propiedad.En otras palabras, el siguiente código hace lo mismo:
var arr = [1, 2, 3]; arr.cookies = 4; alert(arr.length) // 3;
fuente
length
propiedad incorporada .for
ciclo ordinario de0
a.length
. Hazconsole.dir(arr)
para ver el objeto completo. Además, el uso de la notación entre corchetes para acceder a las matrices no es una característica de las matrices, es una característica inherente de los objetos (var obj = {foo: 'bar'}; obj.foo or obj['foo']
).La
length
propiedad devolverá un número uno más alto que el "índice" asignado más alto, donde los "índices" de Array son números enteros mayores o iguales a cero. Tenga en cuenta que JS permite matrices "dispersas":var someArray = []; someArray[10] = "whatever"; console.log(someArray.length); // "11"
Por supuesto, si no existen elementos que a continuación
length
es0
. Tenga en cuenta también quelength
no se actualiza si usadelete
para eliminar el elemento más alto.Pero las matrices son objetos, por lo que puede asignar propiedades con otros nombres de propiedad arbitrarios, incluidos números negativos o fracciones:
someArray[-1] = "A property"; someArray[3.1415] = "Vaguely Pi"; someArray["test"] = "Whatever";
Tenga en cuenta que, detrás de escena, JS convierte los nombres de propiedad en cadenas incluso cuando proporciona un número como
-1
. (Los índices enteros positivos también se convierten en cadenas, para el caso).Métodos de matriz, como
.pop()
,.slice()
, etc., sólo el trabajo sobre los-o de mayor cero enteros "índices", y no en otras propiedades, por lo quelength
es coherente en ese punto.fuente
var a = new Array(9)
, dado ,a
tiene una longitud de 9 y no tiene ningún elemento.Array.slice()
método hace eso. ElString.slice()
método hace lo mismo.Tenga en cuenta que cuando usa un índice de posición (o 0), los valores se colocan dentro de la matriz:
var array = []; array[0] = "Foo"; array[1] = "Bar"; // Result: ["Foo", "Bar"] // Length: 2
Este no es el caso cuando agrega valores que no son índices (no 0-9 +):
var array = []; array[0] = "Foo"; array[1] = "Bar"; array[-1] = "Fizzbuzz"; // Not a proper array index - kill it // Result: ["Foo", "Bar"] // Length: 2
Los valores solo se colocan en la matriz cuando se sigue las reglas. Cuando no lo hace, no se aceptan. Sin embargo, se aceptan en el objeto Array en sí, que es el caso de casi cualquier cosa en JavaScript. Aunque
["Foo", "Bar"]
son los únicos valores en nuestra matriz, aún podemos acceder a"Fizzbuzz"
:array[-1]; // "Fizzbuzz"
Pero tenga en cuenta nuevamente que esto no es parte de los valores de la matriz, ya que su "índice" no es válido. En cambio, se agregó a la matriz como un miembro más. Podríamos acceder a otros miembros de la matriz de la misma manera:
array["pop"]; // function pop() { [native code] }
Tenga en cuenta aquí que estamos accediendo al
pop
método en la matriz, que nos informa que contiene código nativo. No estamos accediendo a ninguno de los valores de la matriz con una clave de "pop", sino a un miembro del objeto de la matriz en sí. Podemos confirmar esto aún más pasando por encima de los miembros públicos del objeto:for (var prop in array) console.log(prop, array[prop]);
Que escupe lo siguiente:
0 Foo 1 Bar -1 Fizzbuzz
De nuevo, está en el objeto , pero no en la matriz .
¡Impresionante pregunta! Seguro que me hizo pensar dos veces.
fuente
["Foo", "Bar"]
pero["Foo", "Bar", -1: "Fizzbuzz"]
marque el violín aquí . Como escribiste, se convierte en una propiedad con la clave -1 pero definitivamente es visible en la salida. De lo contrario, su respuesta es agradable y completa. Si cambia, votaré a favor de nuevo, mi voto en contra fue demasiado duro, pero no puedo eliminarlo; el tiempo expiró.Si realmente desea que se incluyan índices negativos y otros índices en la longitud, cree la funcionalidad usted mismo:
function getExtendedArray() { var a = []; Object.defineProperty(a, 'totalLength', { get : function() { return Object.keys(a).length; } }); return a; }
Entonces por ejemplo:
var myArray = getExtendedArray(); console.log(myArray.totalLength); // 0 myArray.push("asdf"); myArray[-2] = "some string"; myArray[1.7777] = "other string"; console.log(myArray.totalLength); // 3
fuente
if(Number(key) != NaN) length++;
Si desea filtrar los flotantes, agregue&& key % 1 == 0
a la condiciónArray es solo un tipo especial de objeto en JS. Hay una sintaxis especial, que es buena, porque nos permite trabajar con ellos de forma eficaz. Imagínese lo tedioso que sería escribir un literal de matriz de esa manera:
const array = {0: 'foo', 1: 'bar', 2: 'baz'} //etc...
Sin embargo, siguen siendo objetos . Entonces, si lo hace:
const myArray = [42, 'foo', 'bar', 'baz']; myArray[-1] = 'I am not here'; myArray['whatever'] = 'Hello World';
Esas propiedades que no son enteras se adjuntarán a un objeto (qué matriz es), pero algunos métodos nativos como
Array.length
.Puede asumir que el método nativo de 'longitud' es un captador que cuenta todas las propiedades (y los índices son propiedades, mientras que los valores son los valores reales ) convertibles en números enteros positivos o cero. Algo como esta pseudo-implementación:Debido a las especificaciones , el
length
método nativo , como getter (exampleArray.length
), verificará todas las claves ' enteros no negativos menores de 2 32 ', obtendrá la mayor y devolverá su valor numérico + 1.Como setter (
exampleArray.length = 42
), creará algunos espacios vacíos para los índices 'perdidos' si la longitud dada es mayor que el número real de claves enteras no negativas, o eliminará todas las claves enteras no negativas (y sus valores) que no sean mayores que el longitud dada.La pseudo-implementación:
const myArray = { '-1': 'I am not here', // I have to use apostrophes to avoid syntax error 0: 42, 1: 'foo', 2: 'bar', 3: 'baz', whatever: 'Hello World', get myLength() { let highestIndex = -1; for (let key in this) { let toInt = parseInt(key, 10); if (!Number.isNaN(toInt) && toInt > -1) { // If you're not an integer, that's not your business! Back off! if (toInt > highestIndex) highestIndex = toInt; } } return highestIndex + 1; }, set myLength(newLength) { /* This setter would either: 1) create some empty slots for 'missing' indices if the given length is greater than the actual number of non-negative-integer keys 2) delete all non-negative-integer keys (and their values) which are not greater then the given length. */ } } console.log(myArray.myLength); // 4 myArray[9] = 'foobar'; console.log(myArray.myLength); // 10
fuente
Las matrices en JavaScript son en realidad objetos. Simplemente se crean un prototipo del constructor Array.
Los índices de matriz son en realidad claves en un mapa hash, y todas las claves se convierten en cadenas. Puede crear cualquier clave (es decir, "-1"), pero los métodos en Array están diseñados para actuar como una matriz. Entonces,
length
no es el tamaño del objeto, solo se garantiza que sea más grande que el índice entero más grande. De manera similar, la impresiónarr
solo mostrará valores con claves enteras> = 0.Más info aquí.
fuente
Según MDN:
En Javascript, puede establecer una propiedad en cualquier objeto que cree.
var array = new Array(); array = [1,2,3]; array["boom"] = "pow";
De la misma manera, cuando establece un índice negativo, lo almacena como una propiedad en la matriz en lugar de como parte del índice.
array[-1] = "property does not add to array length";
Es por eso que la longitud no lo refleja, pero un bucle for..in lo muestra.
fuente
Cuando utiliza índices no positivos o no numéricos, la matriz se comporta como una matriz asociativa que tiene pares clave-valor.
Para iterar a través de la matriz, puede usar
for(var index in myArray) { document.write( index + " : " + myArray[index] + "<br />"); }
fuente