¿Cómo se implementan 'variables protegidas' en javascript?

var DIM = {
  makeOneDim: function(x) {
    var magic = Math.random();
    return {
      dist: function() {
        return x * magic;
      }
    };
  },
  makeTwoDim: function(x,y) {
    var o = DIM.makeOneDim(x);
    o.dist = function() {       
      magic *= Math.random();
      return Math.sqrt(x*x+y*y) * magic;
      // !! cant access 'private' variable magic !!
    }
    return o;
  }
};
var o = DIM.makeOneDim(123);
var oo = DIM.makeTwoDim(1,2);
console.log(o.dist() + oo.dist());

Sé que en este ejemplo sería posible hacer un 'captador público', pero aún así quisiera mutar la variable mágica dentro del alcance de makeTwoDim y ocultarla de sus instancias.

También sería bueno si de alguna manera pudiera evitar recrear las funciones dist en cada creación de una instancia.

1
iluvAS 14 may. 2016 a las 17:26

5 respuestas

La mejor respuesta

¿Se adapta esto a tus necesidades? Utiliza un patrón de módulo revelador para hacer magic privado y devolver las funciones. Como tal, no es necesario llamar a makeOneDim desde makeTwoDim.

var DIM = (function () {

  var magic = Math.random();

  function makeOneDim(x) {
    return {
      dist: function() {
        return x * magic;
      }
    };
  }

  function makeTwoDim(x, y) {
    return {
      dist: function() {
        magic *= Math.random();
        return Math.sqrt(x * x + y * y) * magic;
      }
    }
  }

  return {
    makeOneDim: makeOneDim,
    makeTwoDim: makeTwoDim
  }

});

var o = DIM().makeOneDim(123);
var oo = DIM().makeTwoDim(1,2);

Demo

0
Andy 14 may. 2016 a las 14:46

Debería poder determinar el valor de magic dentro de makeTwoDim dividiendo o.dist() por x

var o = DIM.makeOneDim(x);    
var magic = o.dist() / x;
console.log(magic)
0
guest271314 14 may. 2016 a las 14:47

Hay muchas maneras de diseñar esto, pero la más simple sería mantener las funciones juntas:

var DIM = {
  makeOneDim: function(x) {
    var magic = Math.random();
    var dist = function() {
      return x * magic;
    };

    var dist2 = function(y, y) {       
      magic *= Math.random();
      return Math.sqrt(x*x+y*y) * magic;
    };

    return {
      dist : dist,
      dist2 : dist2,
    };
  }
};

(y, ¿realmente quiso cambiar el valor de magic con cada llamada?)

0
Malvolio 14 may. 2016 a las 14:45

Necesita crear un entorno con función de alcance.

La forma jQuery:

var myClass;

(function () {
    var a = 0; // private var

    function protect_function() {
        //...
    }

    window.myClass = {
        public_function: function () { }
    };
})();
0
A-312 14 may. 2016 a las 14:54

Sé que es probable que recolecte tomates podridos, pero me gustaría decir que no estoy de acuerdo con el uso de variables "protegidas" o "privadas" en el ámbito de JavaScript OOP. No hay salvaguardas incorporadas en JavaScript, los desarrolladores están condenados a ser mejores que los demás, eso es todo :-D No intentes imitar Java, solo tómalo como una oportunidad para mejorar tus habilidades de programación. Por lo tanto, este código me parece perfecto:

AClass = function () {
  // `rdm` should never change
  this.rdm = Math.random();
};
0
leaf 14 may. 2016 a las 14:55