Private class in JavaScript

5

I'm looking for a way to make both attributes and methods invisible so they are not accessible from outside the class. But I also wanted to use the modern approach to do this (classNameClass {}). After many attempts I have taken a different approach to everything I have found: although it works exactly as I need it, and, in my opinion, it is much simpler and readable, I do not know if this is valid and / or conventional.

Can I do this? Or is there a convention that forbids this approach?

See the code carefully:

'use strict';
//O objetivo dessa class é tornar os dados restritos
function ExemplePrivate(value){
    var _value = value; //Privado
    
    this.set_value = function(val){
        //Poderá fazer uma validação antes
        _value = val;
    }
    this.get_value = function(){
        //Poderá fazer uma validação antes
        return _value;
    }
}

//Class filha que será pública
class ClassPublic extends ExemplePrivate{
    //adicional code
}

 
    var cPublic = new ClassPublic('A class filha foi <b>instanciada</b>');
    document.querySelector('#p1').innerHTML = cPublic.get_value();
    cPublic.set_value('A class filha foi <b>modificada</b>');
    document.querySelector('#p2').innerHTML = cPublic.get_value();
    
    // Note que o resultado é bloqueado
    document.querySelector('#p3').innerHTML += cPublic._value+".";
#p3{color:red}
<!-- Look in JS -->
<p id="p1"></p>
<p id="p2"></p>
<p id="p3"> O resultado para <b>cPublic._value</b> tem que ser <b>undefined</b> porque é invisível: </p>
    
asked by anonymous 08.09.2018 / 16:01

2 answers

1

Module Pattern

From the problem description, where you want to separate the private part from the public part, perhaps what you are looking for is the Module Pattern or something similar. I've already used a variation called Definitive Module Pattern because I think the implementation is clearer. In the link the author also explains how the original pattern works.

Using an example:

var module = (function () {

    function ClassePrivada () {
        this.valor = 30,
        this.setValor = function (val) {
          this.valor = val;  
        }
        this.getValor = function () {
          return this.valor;
        }
    }

    // private
    var _private = {
        valor: 10        
    };
    
    // public
    var _public = {
        getValor: function () { 
          return _private.valor
        },        
        setValor: function (val) {
          _private.valor = val;
        },
        getInstancia: function () {
          return new ClassePrivada();
        }
    };

    return _public;

})();


// funcoes privadas
console.log(module.getValor());
module.setValor(20);
console.log(module.getValor());

// classes privadas
var c = module.getInstancia();
console.log(c.getValor());
c.setValor(40);
console.log(c.getValor());

You can also create a module hierarchy that is interesting and lets you better organize your code by creating a structure similar to namespaces.

If this is not exactly the type of solution you are looking for, I hope it will help you in creating your solution.

    
11.09.2018 / 15:06
4

Power, you can. Do what you want? Do not have undesirable effects? Only you can answer this. If you do everything correctly you can do it. If you are not sure about this and you do not do anything different, do not do it. Worth for anything in programming. Never do anything if you are not sure if the result is exactly what you want, no more, no less.

Do not mind conventions that forbid something. This is called "good practice" and look here on the site for what I think about it. You have to know the why of things, not conventions that tell you to do something.

I find this code ugly because it does not use one-sided class and uses another. If you want to make the class private. I have my doubts if that's what you want. And I think you have addictions in this code, but this is a matter of opinion, even because I'm not sure what you want and especially what you need that is more important than you want.

It has a good practice that says to use getter and setter , but in script languages this makes little or no sense. / p>

If you want to class scale, where you need private class should use TypeScript. Code sample:

module Modulo {
    export class ClassePublica {
        private classePrivada : PrivateClass;
        constructor() {
            this.classePrivada = new ClassPrivada();
        }
        public teste() {
            this.classePrivada.teste();
        }
    }
    class ClassPrivada {
        public teste() {
            console.log('it works');
        }
    }
}

That in JS looks like this:

var Modulo;
(function (Modulo) {
    var ClassePublica = /** @class */ (function () {
        function ClassePublica() {
            this.classePrivada = new ClassPrivada();
        }
        ClassePublica.prototype.teste = function () {
            this.classePrivada.teste();
        };
        return ClassePublica;
    }());
    Modulo.ClassePublica = ClassePublica;
    var ClassPrivada = /** @class */ (function () {
        function ClassPrivada() {
        }
        ClassPrivada.prototype.teste = function () {
            console.log('it works');
        };
        return ClassPrivada;
    }());
})(Modulo || (Modulo = {}));
    
08.09.2018 / 16:43