w3schools tag tab style page for color javascript jquery design-patterns module-pattern

tag - Módulo revelador de Javascript, propiedades públicas.



title of page html (2)

Estoy tratando de ubicarme alrededor del patrón revelador del módulo en javascript. Estoy desconcertado por dos cosas sobre el siguiente fragmento de código.

var Child = function () { var totalPoints = 100; addPoints = function (points) { totalPoints += points; return totalPoints; }; getPoints = function () { return totalPoints; }; return { points: totalPoints, addPoints: addPoints }; }; $(function () { var george = Child(); console.log(george.points); console.log(george.addPoints(50)); console.log(george.points); });

  1. Los tres valores escritos en la consola aquí son 100, 150, 100. Eso me dice que cuando llamo "addPoints" con un valor, la variable totalPoints no se actualiza. Si examino el valor de totalPoints dentro de la función addPoints, se ha incrementado correctamente. ¿Que esta pasando?

  2. Si uso la consola para examinar window.addPoints o window.getPoints, puedo verlo porque no he usado "var" delante de las declaraciones de funciones que se han agregado al ámbito global. ¿No está mal? La mayoría de los ejemplos que estoy viendo parecen hacer esto.

Cualquier puntero recibido con gratitud.


Estás pasando un número aquí:

return { points: totalPoints, addPoints: addPoints };

Esta pieza de código no es diferente de:

return { points: 100, addPoints: addPoints };

Estás pasando el valor ; no es una referencia a totalPoints (este último no es posible en JavaScript). Por lo tanto, cuando totalPoints cambia, el valor en el objeto no cambia.

Usando una función

La forma más sencilla de getPoints esto es usar una función para obtener el resultado más actualizado (como getPoints que ya tiene). Este JSFiddle da un ejemplo completo:

return { points: function(x) { return totalPoints; }, // always up-to-date addPoints: addPoints };

El inconveniente es que la persona que llama ahora debe solicitar points como una llamada de función:

console.log(george.points());

Usando un getters y setters

Otra solución es utilizar getters que le permitirían obtener un valor actualizado con solo george.totalPoints , aunque los getters no son ampliamente compatibles (todavía). Podrías implementar un getter como este:

var obj = {}; obj.points = addPoints; // add a "special" property to the object instead of normal notation Object.defineProperty(obj, "totalPoints", { get: function() { // function that''s executed when you use `.totalPoints` return totalPoints; } }); return obj;

En segundo lugar, la eliminación de var hace que las funciones sean globales, lo que es correcto pero no recomendable. Podría hacer una declaración var utilizando comas, si eso es lo que quiere decir:

var totalPoints = 100, // expands to three `var` statements, so no addPoints = ..., // global variables getPoints = ...;


Esta es una solución ligeramente diferente, que no requiere un getter / setter y conserva totalPoints como una propiedad.

var Child = function () { var _api; return _api = { addPoints: addPoints, points: 100 }; /* ----------- */ function addPoints(points) { _api.points += points; return _api.points; }; };