Tengo el siguiente código:
const ships = (length) => { isSunk = false console.log('BEFORE: ' + isSunk) const shipSize = length let hits = [] const hitLocation = location => { hits.push(location); isSunk = true; console.log('INSIDE: ' + isSunk) } console.log('AFTER: ' + isSunk) return { isSunk, hitLocation, hits, shipSize } } const two = ships(2) two.hitLocation(1) two.hitLocation(2) console.log('FINAL: ' + two.isSunk) console.log('HITS: ' + two.hits) ¿Hay alguna razón por la que isSunk no se guarde como true cuando lo llamo al final?
¿Se debe a las funciones anidadas?
Cuando establece el booleano en el objeto, es ese valor. No es una referencia a la variable. Entonces, cuando cambia la variable, el valor que guardó dentro del objeto que devolvió no se actualiza.
Puedes usar una función para obtener el valor.
const ships = (length) => { isSunk = false console.log('BEFORE: ' + isSunk) const shipSize = length let hits = [] const hitLocation = location => { hits.push(location); isSunk = true; console.log('INSIDE: ' + isSunk) } console.log('AFTER: ' + isSunk) return { isSunk: () => isSunk, hitLocation, hits, shipSize } } const two = ships(2) two.hitLocation(1) two.hitLocation(2) console.log('FINAL: ' + two.isSunk())Otra opción es usar una clase.
class Ship { hits = []; constructor(length) { this.shipSize = length; } get isSunk() { return this.hits.length === this.shipSize; } hitLocation (location) { this.hits.push(location); console.log('INSIDE: ' + this.isSunk) } } const two = new Ship(2) two.hitLocation(1) two.hitLocation(2) console.log('FINAL: ' + two.isSunk)La razón por la que esto sucede es que isSunk es solo una variable local y un valor en contraste con hits que también es una variable local pero una matriz y, por lo tanto, solo una referencia, no un valor . A medida que devuelve el objeto al llamar a ship() , estos valores y la referencia se devuelven en un objeto.
Ahora, cuando llama a hitLocation() , utiliza las coincidencias de la variable hits para agregar una entrada a la matriz y, como la matriz es solo una referencia, las coincidencias de la variable hits y las hits en los two objetos tienen la misma referencia, por lo que apuntan a la misma memoria. ubicación, por lo que la actualización se puede ver utilizando el objeto devuelto.
Por otro lado hitLocation() también modifica la variable local isSunk pero como no devuelve eso y no es una referencia, el objeto almacenado en la variable two no se actualiza.
La mejor manera de arreglar esto en mi mente es usar una clase en lugar de un objeto aquí. Esto será mucho más conciso y claro que devolver y/o pasar el objeto sobre el que desea realizar alguna acción a una función todo el tiempo.