Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Sobre a afirmação de atributos não poderem ser privados no javascript

De acordo com o que já li sobre o assunto, uma maneira de tornar alguns atributos privados é retornar uma função e utilizar de "closures" como abaixo.

var stack = new (function Stack() {
    var array = [],
        index = -1;

    return {
      push: function (value) {
        array[index += 1] = value
      },
     pop: function () {
       var value = array[index];
       if (index >= 0) {
         index -= 1
       }
       return value
     },
     isEmpty: function () {
       return index < 0
     }
   }
 });

console.log(stack.isEmpty());//true stack.push('hello');//false stack.push('JavaScript');//JavaScript console.log(stack.isEmpty());//hello console.log(stack.pop());//true console.log(stack.pop());//true console.log(stack.isEmpty());//undefined

os comentários são os retornos.

Essa abordagem protegeria de alterações, dos parametros, criando as variáveis privadas.

9 respostas

Isso que você leu na internet não tem relação com design de classes (apesar do autor do código que você postou tentar, sem estar antenado das consequências de seu código, criar algo parecido). Vejamos um exemplo que usa essa estratégia usando ES5:

function Pessoa(nome) {

   var nome = nome;


   this.getNome = function() {

        return nome;   
   };

   this.setNome(nome) {
           nome = nome;
   }
}

var pessoa = new Pessoa('Flávio Almeida');
console.log(pessoa.getNome());

Veja que desse jeito a única maneira de acessar a variável (VEJA NÃO É UM ATRIBUTO) é através de getNome (closure em ação). Contudo essa solução possui problemas de performance, pois cada instância da função construtora Pessoa terá os métodos getNome e setNome e isso é muito ruim em termos de performance.

É por isso que esses métodos são colocados no prototype e quando fazemos isso, não podemos usar variáveis como se fosse atributos porque o prototype não terá acesso à elas. E por isso que usamos propriedades:

function Pessoa(nome) {

   this.nome  = nome;

}

Pessoa.proprotype.getNome = function() {

    return this.nome;   
};

Pessoa.prototype.setNome(nome) {

    this.nome = nome;
}

var pessoa = new Pessoa('Flávio Almeida');
console.log(pessoa.getNome());

var pessoa2 = new Pessoa('Almeida Flavio');
console.log(pessoa2.getNome());

Nesse caso o getNome e o setNome é o mesmo para todos as instâncias. Tem que ficar esperto com o que lemos na internet e seu contexto, o que você viu é verdadeiro, mas não usamos para o design de classes (pode até usar, mas se seu navegador vai explodir é responsabilidade sua). Alias, o ES6 (ES2015) é uma atalho para a forma que eu acabei de escrever, ou seja, quando você cria uma classe e define métodos ele converte para debaixo dos panos para essa estrutura com proptotype, porque a comunidade reconhece essa forma com a mais indicada durante anos.

Contudo, essa estrutura que você mostrou é interessante quando trabalhamos com módulos. Você verá isso ao longo do treinamento e vai gostar, com certeza (no módulo 3 em desenvolvimento precisamos usar esse recurso para lidar com conexão do IndexedDB).

Talvez esse post de um colega meu possa esclarecê-lo ainda mais:

http://blog.caelum.com.br/criacao-de-objetos-em-javascript/

Mas veja, tudo isso é ES5! Nosso curso é de ES6 (ES2015).

E ainda tem o post do "careca" sobre vantagem e desvantagens dessas abordagens. Inclusive uma sua Symbol:

http://www.2ality.com/2016/01/private-data-classes.html

Aliás, você foi o primeiro aluno em mais de 1209 a dar nota 6 para o treinamento. Nunca havia recebido uma nota inferior a 9.

Fico triste do treinamento não ter atendido suas expectativas, ainda mais, sendo um treinamento avançado. Você tem um repositório do github para que eu possa ver seu código e entender melhor seu perfil de desenvolvedor? Isso me ajuda a calibrar melhor o treinamento tornando-o ainda melhor para diferentes perfis.

Leonardo?

Não tem repositório git? Se não tiver não faz mal. Essa questão ficou esclarecida?

Desculpe a demora em responder a sua questão. De fato o comparativo com o seu curso foi baseado com essa leitura que fiz: https://leanpub.com/javascript-allonge/read

Que aliais foi de onde eu tirei a ideia do que propus no tópico: "how do we hide state using javascript?"

Mas concluindo, sim a questão ficou esclarecida sim.

solução!

Beleza Leonardo! O importante aqui é ficar atento às vantagens e desvantagens dessa abordagem. O lance do prototype é muito importante por questões de performance.

Inclusive, no mesmo link que você postou o autor aborda esse assunto e escreve o seguinte:

A Class By Any Other Name

JavaScript has “classes,” for some definition of “class.” You’ve met them already, they’re constructors that are designed to work with the new keyword and have behaviour in their .prototype element. You can create one any time you like by:

E olha o exemplo que ele dá:

function Todo (name) {
  this.name = name || 'Untitled';
  this.done = false;
 };

Todo.prototype.do = function () {
  this.done = true;
 };

Todo.prototype.undo = function () {
    this.done = false;
};

O mais fantástico é que o ES6 já se encarrega de fazer tudo isso por baixo dos panos.

Sucesso e bom estudo!