Estoy revisando un tutorial de las escuelas W3 sobre controladores de juegos y hay una expresión myGameArea.keys = (myGameArea.keys || []) que tengo problemas para entender y sería genial si alguien pudiera explicar en detalle cuál es el lógica detrás.
¿Qué sucede si se presiona más de una tecla al mismo tiempo?
En el ejemplo anterior, el componente solo puede moverse horizontal o verticalmente. Ahora queremos que el componente también se mueva en diagonal.
Cree una matriz de teclas para el objeto myGameArea e inserte un elemento para cada tecla que se presiona, y asígnele el valor true , el valor permanece verdadero hasta que la tecla ya no se presiona, el valor se vuelve falso en la función de escucha de eventos keyup:
window.addEventListener('keydown', function (e) { myGameArea.keys = (myGameArea.keys || []); myGameArea.keys[e.keyCode] = true; }) window.addEventListener('keyup', function (e) { myGameArea.keys[e.keyCode] = false; }) var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('keydown', function (e) { myGameArea.keys = (myGameArea.keys || []); myGameArea.keys[e.keyCode] = true; }) window.addEventListener('keyup', function (e) { myGameArea.keys[e.keyCode] = false; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } } function updateGameArea() { myGameArea.clear(); myGamePiece.speedX = 0; myGamePiece.speedY = 0; if (myGameArea.keys && myGameArea.keys[37]) {myGamePiece.speedX = -1; } if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.speedX = 1; } if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speedY = -1; } if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speedY = 1; } myGamePiece.newPos(); myGamePiece.update(); }En la mayoría de los lenguajes de programación, || es un operador que toma dos valores booleanos y les realiza un OR lógico. ( true || false es true , etc.)
Algunos lenguajes, principalmente los tipificados dinámicamente en mi experiencia, generalizan la noción de || para trabajar con otros tipos de datos también.
En JavaScript, || significa lo siguiente:
0 , false , "" , null , undefined , NaN ), devuelva el segundo valor. Si conecta algunos valores booleanos, puede ver que este comportamiento imita cómo || trabajar en otros idiomas.
Debido a este comportamiento, || gana un uso secundario como operador de "valor predeterminado", es decir, "use este valor a menos que sea falso, en cuyo caso use este otro valor en su lugar".
Por ejemplo:
let greeting = x || "Hello"; En el código anterior, el greeting se establecerá en x a menos que x sea falso, en cuyo caso se establecerá en "Hello" .
Igualmente,
this.foo = this.foo || "Yo!"; El código anterior inicializará this.foo a "Yo!" si aún no existe (o existe pero tiene un valor falso).
Editar:
Mirando este ejemplo específico en la publicación de OP:
window.addEventListener('keydown', function (e) { myGameArea.keys = (myGameArea.keys || []); myGameArea.keys[e.keyCode] = true; }) La línea myGameArea.keys = (myGameArea.keys || []); asegura que la matriz myGameArea.keys existe, ya que nunca se crea antes de que el detector de eventos se registre y se invoque potencialmente. Podría agregar explícitamente una keys: [] al objeto myGameArea para eliminar la necesidad de esta línea por completo.
Además, el código también contiene usos similares del operador && . Como con || , también se ha generalizado en JavaScript. Funciona así:
Mirando su uso en la declaración if:
if (myGameArea.keys && myGameArea.keys[37]) { /*...*/ } myGameArea.keys && es una forma de cortocircuitar la segunda mitad de la condición. Si nunca se creó myGameArea.keys (por ejemplo, porque nunca se presionó ningún botón), omitimos el resto de la condición que, de lo contrario, se habría bloqueado, ya que myGameArea.keys no estaría undefined y no se puede indexar ( [37] ) en undefined valor.