En Javascript, el comando length es uno de los más utilizados. Para todos los desarrolladores, length es una de las piezas claves a la hora de recorrer arrays. Sin embargo, además de como una propiedad, funciona también como un interesante método aplicable a funciones que permite construir arquitecturas de objetos muy flexibles. Repasemos todos sus usos con sus correspondientes ejemplos en cada caso:
Length En cadenas ( String )
El valor de la propiedad length en una cadena es igual a su número de caracteres.
Sin embargo, hay que tener en cuenta que el UTF-16, el formato para cadenas utilizado en Javascript, utiliza una codificación de 16 bits para representar los caracteres más usuales; en el caso de aquellos más raros, se necesitan dós unidades de código por lo que puede darse el caso de que el valor length no se corresponda exactamente con el número de caracteres utilizados en una cadena.
var foo = 'Hello World'; console.log( foo.length ); // 11 var bar = '\uD834\uDD1E'; // MUSICAL SYMBOL G CLEF (D834 y DD1E) console.log( bar.length ); // 2 |
Length en arrays ( Array )
En un array, la propiedad length devuelve el número de elementos que contiene, independientemente de si se tratan tanto de valores falsy como truthly:
var foo = [ 0, 1, 2, '', 'foo', false, undefined, NaN, Infinity, [], {} ]; console.log( foo.length ); // 11 |
Editando esta propiedad, podemos truncar un Array en cualquier momento:
var foo = [ 1, 2, 3, 4, 5, 6, 7 ]; foo.length = 3; console.log( foo ); // 1, 2, 3 |
Sin embargo, una vez truncado, ampliar la longitud del array no produce ningún efecto:
foo.length = 6; console.log( foo ); // 1, 2, 3 |
Como hemos mencionado al principio, length es el comando clave para recorrer un array en Javascript:
var foo = [ 1, 2, 3, 4, 5, 6 ]; for( i = 0, j = foo.length; i < j; i++ ){ foo[ i ] = foo[ i ] * 2; // multiply each value by 2 } console.log( foo ); // [2, 4, 6, 8, 10, 12] |
En números y objetos ( Number y Object )
Las variables primitivas Number y Object no tienen propiedad length y devuelven por tanto undefined:
var foo = 12; var bar = { id : '12' }; console.log( foo.length ); // undefined console.log( bar.length ); // undefined |
En funciones ( Function )
En el caso de las funciones, length no es una propiedad sino un método. Invocado directamente sobre el nombre de una función declarada, devuelve el número de argumentos que espera:
var foo = function( param1, param2, param3 ){ // Do something... } console.log( foo.length ); // 3 |
Invocada en el interior de la misma, puede darnos el número de argumentos que se han pasado a través de arguments:
var foo = function(){ return arguments.length; } console.log( foo( 'param1', 'param2', 'param3', 'param4' ) ); // 4 |
Conociendo ambos datos, podemos crear una función que nos permita sobreescribir métodos dependiendo de los valores que tengamos:
function addMethod(object, name, fn){ // Save a reference to the old method var old = object[ name ]; // Overwrite the method with our new one object[ name ] = function(){ // Compare incoming arguments with expected if ( fn.length == arguments.length ) { // If there was a match, run the function return fn.apply( this, arguments ); } else if ( typeof old === "function" ) { // Otherwise, fallback to the old method return old.apply( this, arguments ); } }; } |
Tomemos ahora un objeto con varios métodos de igual nombre que devolverán un valor u otro dependiendo de los argumentos:
function Users(){ var users = [ 'Philip K Dick', 'Isaac Asimov', 'Philip J Farmer', 'Orson Scott Card' ]; // No arguments addMethod( this, 'find', function(){ return users; }); // One argument addMethod( this, 'find', function( name ){ var retUsers = []; for ( var i = 0; i < users.length; i++ ){ if( users[ i ].indexOf( name ) == 0 ){ retUsers.push( users[ i ] ); } } return retUsers; }); // Two arguments addMethod( this, 'find', function( first, last ){ var retUsers = []; for( var i = 0; i < users.length; i++ ){ if( ( users[ i ].indexOf( first ) != -1 ) && ( users[ i ].indexOf( last ) != -1) ){ retUsers.push( users[ i ] ); } } return retUsers; }); } var users = new Users(); console.log( users.find() ); // ["Philip K Dick", "Isaac Asimov", "Philip J Farmer", "Orson Scott Card" ] console.log( users.find( 'Isaac' ) ); // ["Isaac Asimov"] console.log( users.find( 'Philip' ) ); // ["Philip K Dick", "Philip J Farmer"] console.log( users.find( 'Orson', 'Card' ) ); // ["Orson Scott Card"] console.log( users.find( 'William', 'Farmer' ) ); // [] |
En el ejemplo anterior, hemos creado tres métodos con el mismo nombre pero con un comportamiento diferente basado en el número de argumentos. Esto ofrece una gran flexibilidad a la hora de crear arquitecturas de objetos complejos que puede resultar interesante de explotar.
Y hasta aquí este análisis sobre el comando length. Si tenéis más ejemplos de uso interesantes, no dudéis en compartirlos en los comentarios!
Excelente pagina, muy util para los que gustan de programar en JavaScript…
Saludos
Excelente me ha ayudado mucho ya que estoy comenzando en javascript 😛
Acabo de flipar con el ejemplo de length en funciones y como se crean un mismo método para diferentes argumentos. Mucho debería interiorizar yo este ejemplo para extrapolarlo a otros casos, pero tiene una pinta con mucho potencial. De momento este caso concreto me habría resultado más fácil de entender y hacer con alguno de los patrones que explicas en otros posts. Por ejemplo este: http://jsfiddle.net/QpZx2/
¿Por qué no me funciona el operador lenght?
He copiado el ejemplo de lenght en cadenas y también en arrays y en los dos casos me ha salido undefined.
Gracias