Propriedades protegidas em Javascript

ES 5 introduziu algumas coisas muito legais em relação aos objetos

Uma coisa que muitas pessoas me dizem é “Javascript é legal e outras coisas, mas você não pode ter propriedades privadas ou protegidas em objetos, certo?”.
Esse é o ponto onde você gosta que eu fique longe de qualquer objeto pontiagudo.

Como alguns de vocês devem saber, as propriedades privadas são simples, se você seguir o padrão de módulo em Javascript:

var Cat = {};
Cat.create = function (config) {
var that = config || {name: "Kitty"};
var sound = "Meow";

that
.says = function() { return sound; };
return that;
};

var myCat = Cat.create();
console
.log(myCat.name + ": " + myCat.says()); // "Meow"
myCat
.sound = "nyan";
console
.log(myCat.name + ": " + myCat.says()); // still "Meow"

Portanto, neste exemplo, temos uma propriedade privada “sound” e você deve usar o getter para acessá-la.

Mas e as propriedades protegidas? O grande problema com a abordagem aqui é que não podemos realmente aproveitar a passagem da propriedade “sound” usando config, sem perder a proteção contra adulteração. Claro, existem soluções (por exemplo, especificação de parâmetros adicionais, etc.) – mas há uma maneira mais elegante:

ES5 é útil aqui com o adorável Object.defineProperty, que nos permite adicionar uma propriedade a um objeto com características especificadas, como ser somente leitura.

Portanto, uma versão estendida pode ter a seguinte aparência:

var Cat = {};
Cat.create = function (config) {
var that = config || {name: "Kitty"};

Object.defineProperty(that, "sound", {
value: (config && config.sound) || "Meow",
writable
: false
});

that
.says = function() { return this.sound; };
return that;
};

var myCat = Cat.create();
alert
(myCat.name + ": " + myCat.says()); // "Meow"
myCat
.sound = "nyan";
alert
(myCat.name + ": " + myCat.says()); // still "Meow"

var nyanCat = Cat.create({name: "Nyan Cat", sound: "Nyan"});
alert
(nyanCat.name + ": " + nyanCat.says()); // "Nyan"
nyanCat
.sound = "Mew";
alert
(nyanCat.name + ": " + nyanCat.says()); // still "Nyan"

Funky, não é?

Com isso, podemos facilmente entregar atributos que não queremos dar acesso de gravação ao público, mas ser capazes de ajustá-los de dentro da classe em que estamos.

Como herança pode ser tratada por meio do parâmetro “config” também, você tem algo como variáveis ​​protegidas (apesar do fato de que ainda são visíveis ao público).