Ver Mensaje Individual
  #9 (permalink)  
Antiguo 12/02/2012, 16:24
Avatar de zerokilled
zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: manejar ciclo de varios select options

ciertamente que tienes una comprensión bien desordenada. quizás, parte de ello es mi culpa por asumir que ya tienes algunos fundamentos en javascript. veamos como podemos disipar la niebla.

[ ] (corchetes)
en javascript, los corchetes tienen varios usos: crear un array literal, accesar elementos de un array (ya sea para leer un elemento o asignar un valor), o accesar una propiedad de un objeto — al menos esos son los usos que primero me vienen a la mente. no creo que en algún momento mencionara que no tienes que usar los corchetes cuando manejaras el array. en un array, el uso de los corchetes es sí o sí; pues así es como se accesan los índices. por tanto, mat + a es muy distinto de mat[a]. el primero intenta concatenar un objeto array con un número, mientras que el segundo significa accesar al índice del array. estoy casi seguro que en eso estás claro. lo que te pudo haber confundido fue la explicación sobre el keyword var y el nombre mat[a]; a continuación lo explicaré.

var mat[a]
var es un keyword que se utiliza para declarar o iniciar una variable. en tu caso, mat es un array que lo has inicializado así... var mat = new Array(14). parece que tu forma de visualizarlo es que debes declarar el índice de un array como si fuera una variable. eso es incorrecto, porque los índices de array no son variables; simplemente son elementos. al utilizar una expresión tal que var mat[a], javascript entiende que el nombre de la variable a declarar es mat[a], lo cual produce un error porque el nombre contiene caracteres inválidos. lo que tú quieres hacer no es declarar una variable con nombre mat[a], sino asignar un valor al array mat indicando como índice el valor de la variable a. de ahí la mención de que la declaración var en esa línea en particular está mal. simplemente elimina el keyword var.

corchetes como accesor de propiedades
la sintaxis de uso creo que ya está bastante explicada en los mensajes anteriores. pero aún tienes error en cómo se realiza la sustitución. pongamos esta norma básica: antes de un par de corchete no puede haber un punto; luego de los corchetes debe seguir un punto u otro par de corchete; dos o más pares de corchetes seguidos es válido. veamos las premisas en práctica.
Código:
// primera premisa
document.['form1']; // produce error, hay un punto antes de los corchetes
document['form1']; // forma correcta

// segunda premisa
document['form1']Materia1; // produce error, luego de los corchetes falta el punto
document['form1'].Materia1; // forma correcta con el punto
document['form1']['Materia1']; // forma correcta con corchete

// tercera premisa, la última línea de la segunda premisa es un ejemplo, pero expondré otros ejemplos válidos
[true, false, null, undefined, 0, ""]['length']; // el primer par de corchete es un array literal, el segundo es el accesor a la propiedad length

self['document']['forms'][0]['elements'][0]['value'];
// este ejemplo accesa a la propiedad value del primer campo en el primer formulario del documento

// nótese el error de esta línea, no cumple con la segunda premisa. 
// en particular, falta un punto luego de los corchetes porque haz indicado el nombre de la propiedad
document.form1['"Materia"+a']value;
¿qué va dentro de los corchetes?
en teoría, puede ir cualquier expresión que evalue a un valor. dicho de otra forma, cualquier expresión que puedas almacenar en una variable. incluso podrías encontrar expresiones un tanto descabellado en la sintaxis de corchete. en el caso de los objetos, se supone que dicho valor evalue a un string que represente el nombre de una propiedad. en los ejemplos anteriores utilicé directamente un string porque no tenía la necesidad de componer un string con otro valor. es decir, no necesariamente tienes que encerrar todo en comillas como lo muestras en el código. en tu ejemplo anterior, javascript entiende que el nombre de la propiedad es "Materia"+a porque se lo haz indicado como un string. es decir, lo haz envuelto todo en comillas simples. a continuación varios ejemplos de cosas válidas e inválidas.

Código:
// partimos de un objeto vacío para que se pueda apreciar el contexto en que se aplica
var obj = {}; // por si las dudas, es un objeto literal, o lo mismo que new Object()

// se invoca el método toString(). no hay ninguna expresión, solo una variable
var s = "toString";
obj[s]();

// se declaran dos propiedades, t, f. nótese la operación ternaria para accesar uno u otro.
// devuelve el boolean false. la condición de la operación es true, por tanto dicha operación
//  evalua y devuelve la expresión del componente verdadero. es decir, condicion? cierto: falso. en este caso,
// la expresión devuelta es el string "t" y da como resultado obj["t"] y finalmente obtienes el boolean false.
obj[f] = true;
obj[t] = false;
obj[true? 't': 'f'];

// este otro ejemplo utiliza el valor devuelto por una función
function dec2hex(n){
return "x"+ parseInt(n, 10).toString(16);
}

// los espacios están simplemente para legibilidad, no tienen ningún efecto salvo si es parte de un string
obj[ dec2hex(16) ] = 16;
obj[ dec2hex(100) ] = 100;
obj.x64; // devuelve el valor 100

// incluso es válido —aunque quizás falto de sentido— utilizar tipos de datos compuestos. no estoy seguro,
// que exactamente hace javascript con dichos valores, a mi entender lo convierte a string
obj[null]  = "is_null";
obj[ function(){} ] = "is_function";
obj[ {} ] = "is_object";
obj[ [] ] = "is_array";

fn = function(){};
obj[ document.getElementById('un_id_que_no_existe') ]; // devuelve "is_null" porque getElementById devuelve el valor null
obj[fn]; // devuelve "is_function"

obj[ new Object() ]; 
// devuelve "is_object" pese a que new Object() es una instancia distinta del objeto literal 
// cuando se creo que la propiedad, es decir obj[ {} ]

obj[ new Array() ]; // devuelve "is_array". lo mismo como el caso de new Object() pero con el array


// expresiones inválidas, practicamente cualquier sentencia que no se pueda almacenar en una variable o que no devuelve un valor
// por instancia, intentamos el equivalente del operador ternario anterior pero con if/else
obj[if(true) "f"; else "t"];

obj[for(var bool = true; bool; bool = !bool) null];