Lo importante a tener en cuenta aquí es que, dado que Javascript es un lenguaje dinámico , cada objeto es, esencialmente, solo un hash-map glorificado ( con algunas excepciones ). Y se puede acceder a todo en un objeto Javascript de dos maneras: notación de corchetes y notación de puntos.
Revisaré rápidamente las dos anotaciones respondiendo la primera parte de su pregunta, y luego pasaré a la segunda parte.
Notación de corchetes
Este modo es más similar al acceso a hashmaps y matrices en otros lenguajes de programación. Puede acceder a cualquier componente (datos (incluidos otros objetos) o función) utilizando esta sintaxis.
Esto es exactamente lo que estás haciendo en tu ejemplo. Tienes 'a'
, que es una cadena (y no un carácter literal, como si estuviera en un lenguaje como C ++).
Usando la notación de corchetes, accede a su toUpperCase
método Pero acceder a él todavía no es suficiente; simplemente escribir alert
, por ejemplo, en Javascript, no llama al método. Es solo una declaración simple. Para llamar a la función, debe agregar el paréntesis: alert()
muestra un cuadro de diálogo simple que contiene undefined
, ya que no recibió parámetros. Ahora podemos usar este conocimiento para descifrar su código, que se convierte en:
alert('a'.toUpperCase());
Lo cual es mucho más legible.
En realidad, una buena manera de entender esto un poco mejor es ejecutar el siguiente Javascript:
alert(alert)
Esto llama alert
al pasarle un objeto de función, también alert
, sin ejecutar también la segunda alerta. Lo que se muestra (en Chrome 26, al menos) es lo siguiente:
function alert() { [native code] }
Vocación:
alert(alert())
muestra dos cuadros de mensaje consecutivos que contienen undefined
. Esto es fácil de explicar: el interno alert()
se ejecuta primero, se muestra undefined
(porque no tenía ningún parámetro) y no devuelve nada. La alerta externa recibe el valor de retorno de la alerta interna, que no es nada, y también se muestra undefined
en un cuadro de mensaje.
¡Pruebe todos los casos en jsFiddle!
Notación de punto
Este es el enfoque más estándar, que permite acceder a los miembros de un objeto utilizando el .
operador dot ( ). Así es como se vería su código en notación de puntos:
alert('a'.toUpperCase())
Mucho más legible. Entonces, ¿cuándo debemos usar la notación de puntos y cuándo debemos usar la notación de corchetes?
Comparación
La principal diferencia entre los dos métodos es semántica. También hay algunos otros detalles, pero los abordaré en un segundo. Lo más importante es lo que realmente quiere hacer: una regla general es que use la notación de puntos para los campos y métodos bien establecidos que tiene un objeto, y la notación de corchetes para cuando realmente está usando su objeto como un mapa hash .
Un gran ejemplo de por qué esta regla es tan importante se puede mostrar en su ejemplo, ya que el código está usando la notación de corchetes en un lugar donde la notación de puntos hubiera sido mucho más sensible, hace que el código sea más difícil de leer. Y eso es algo malo, porque el código se lee muchas veces más de lo que se escribe .
En algunos casos, debe usar la notación de corchetes, incluso si usar la notación de puntos fuera más sensato:
si un miembro de un objeto tiene un nombre que contiene uno o más espacios o cualquier otro carácter especial, no puede usar la notación de puntos: foo.some method()
no funciona, pero foo["some method"]()
sí;
si necesita acceder dinámicamente a los miembros de un objeto, también está atrapado usando la notación de corchetes;
Ejemplo:
for(var i = 0; i < 10; ++i) {
foo["method" + i]();
}
La conclusión es que debe usar la sintaxis de paréntesis cuando use el objeto como un mapa hash ( foods["burger"].eat()
) y la sintaxis de puntos cuando trabaje con campos y métodos "reales" ( enemy.kill()
). Dado que Javascript es un lenguaje dinámico, la línea entre los campos "reales" y los métodos de un objeto y "otros" datos almacenados dentro puede volverse bastante borrosa. Pero siempre que no los mezcles de manera confusa, deberías estar bien.
Ahora, sobre el resto de su pregunta (¡finalmente!: P).
¿Cómo puedo estar seguro de que el método siempre será miembro de obj?
No puedes Intentalo. Intenta llamar derp
a una cadena. Obtendrá un error en las líneas de:
Uncaught TypeError: Object a has no method 'derp'
Es una función genérica llamar a CUALQUIER método en CUALQUIER objeto. ¿Pero eso significa que el método especificado ya será un miembro implícito del objeto especificado?
Sí, en tu caso tendría que ser así. De lo contrario, terminará con el error que mencioné anteriormente. Sin embargo, no tiene que usar return obj[method]();
en la callMethod()
función. Puede agregar su propia funcionalidad que luego utiliza la función de mapa. Aquí hay un método codificado que convierte todas las letras en mayúsculas:
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
El código en el tutorial al que se vinculó utiliza funciones parciales . Son un concepto complicado por sí mismos. Leer más sobre ese tema debería ayudar a aclarar las cosas de lo que podría hacerlo.
Nota: este es el código de la función de mapa utilizada por el código en la pregunta, fuente aquí .
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}
arr[5]
. Si los números en los nombres de identificadores válidos que podrían utilizar la notación de puntos:arr.5
.