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

Não existe atributo privado em js?

Há um tempo atrás li que para criar um atributo privado de uma classe, bastava cria-lo como varao invés de passar um this. Por exemplo:

class Carro {

    var velocidade = 10;

    this.acelerar = function(x) {
        velocidade +=x;
    }

    this.desacelerar = function(x) {
        velocidade -= x;
    }
}

Dessa forma a velocidade só poderia ser modificada com os métodos de acelerar e desacelerar.

No curso é dito que existe a convenção de colocar um underline(_) na frente do atributo para indicar que é um atributo privado, mas nada impede efetivamente de ele ser acessado e/ou modificado.

Se não me engano, com TypeScript podemos usar o modificador de acesso private, mas isso é assunto pra outro curso.

Quais são as formas de tornar um atributo privado? Quando pergunto isso também gostaria de saber as formas pré-ES6, pós-ES6, good-patterns e bad-patterns.

3 respostas

Olá! O código que você escreveu não é um código válido do ES6, ele não passa na validação da sintaxe. Então, fica difícil eu entender a mecânica dele. Você chegou a testá-lo?

Não há atributos privados em JavaScript, apesar de estar no formo uma atualização da linguagem para permitir isso.

Você pode acompanhá-la aqui, inclusive ir se habituando com a linguagem.

https://github.com/tc39/proposal-class-fields

Segue um exemplo diretamente a proposta em andamento:

class Counter extends HTMLElement {
  #x = 0;

  clicked() {
    this.#x++;
    window.requestAnimationFrame(this.render.bind(this));
  }

  constructor() {
    super();
    this.onclick = this.clicked.bind(this);
  }

  connectedCallback() { this.render(); }

  render() {
    this.textContent = this.#x.toString();
  }
}
window.customElements.define('num-counter', Counter);

Atributos privados serão definidos através de this.#.

Sucesso e bom estudo!

Perdão, eu escrevi o formato como ES6, mas o que eu vi não usa "class".

var Car = function() {

    var velocidade = 10;

    this.acelerar = function(x) {
        velocidade +=x;
    };

    this.desacelerar = function(x) {
        velocidade -= x;
    };
}

Eu tinha visto em um desafio da FreeCodeCamp e também gostaria de saber se é uma forma válida, mas como aparentemente ele não usa ES6, suponho que não exista uma forma (fora do forno e servida na mesa) para criar atributos privados, certo?

solução!

O problema é de performance e de acesso da propriedade encapsulada pela closure no prototype chain. Cada instância terá repetido os mesmos métodos, diferente se você tivesse adicionado os métodos no prototype. Mas se adicionar no prototype não terá acesso às variáveis encapsuladas pela closure.

Nesse post da parceira da alura, a Caelum, é explicado as vantagens e desvantagens de abordagem, sem citar o de classes:

http://blog.caelum.com.br/reaproveitando-codigo-com-javascript-heranca-e-prototipos/

Vale a pena a leitura, pois minha explicação vai nesse sentido.