Escopo de Objetos ECMAScript

O escopo é o alcance de aplicação das variáveis.

Escopos público, privado e protegido

Conceito

Em designs de programas orientados a objetos tradicionais, o foco está nos escopos públicos e privados. As propriedades do escopo público podem ser acessadas externamente ao objeto, ou seja, após a criação de uma instância do objeto pelo desenvolvedor, podem ser usadas suas propriedades públicas. Enquanto isso, as propriedades do escopo privado podem ser acessadas apenas dentro do objeto, o que significa que, para o mundo exterior, essas propriedades não existem. Isso significa que se uma classe definir propriedades e métodos privados, suas subclasses também não poderão acessá-los.

O escopo protegido também é usado para definir propriedades e métodos privados, mas esses atributos e métodos também podem ser acessados por subclasses.

O ECMAScript possui apenas escopo público

Discutir sobre esses escopos no ECMAScript é praticamente inútil, pois no ECMAScript existe apenas um tipo de escopo - o escopo público. Todas as propriedades e métodos de todos os objetos no ECMAScript são públicos. Portanto, ao definir suas próprias classes e objetos, deve-se ser extremamente cuidadoso. Lembre-se de que todas as propriedades e métodos são públicas por padrão!

Solução sugerida

Muitos desenvolvedores propuseram padrões eficazes de escopo de atributos na internet, que resolveram este problema do ECMAScript.

Devido à falta de escopo privado, os desenvolvedores determinaram um convenção, que diz quais propriedades e métodos devem ser considerados privados. Esta convenção determina que os atributos sejam precedidos e sucedidos por sublinhados:

obj._color_ = "blue";

Neste código, a propriedade color é privada. Observe que o sublinhado não muda o fato de que a propriedade é um atributo público, ele apenas informa aos outros desenvolvedores que deve ser vista como privada.

Alguns desenvolvedores também gostam de usar sublinhado para indicar membros privados, por exemplo: obj._color.

Escopo estático

As propriedades e métodos definidos pelo escopo estático podem ser acessados em qualquer momento a partir do mesmo local. No Java, uma classe pode ter propriedades e métodos, sem a necessidade de instanciar o objeto da classe para acessar essas propriedades e métodos, por exemplo, a classe java.net.URLEncoder, cuja função encode() é um método estático.

O ECMAScript não tem escopo estático

De forma rigorosa, o ECMAScript não tem escopo estático. No entanto, ele pode fornecer propriedades e métodos para o construtor. Lembram-se, o construtor é apenas uma função. Função é um objeto, e os objetos podem ter propriedades e métodos. Por exemplo:

function sayHello() {
  alert("hello");
}
sayHello.alternate = function() {
  alert("hi");
}
sayHello(); // output "hello"
sayHello.alternate(); // output "hi"

TIY

Aqui, o método alternate() é na verdade um método da função sayHello. É possível chamar sayHello() como uma função convencional para output "hello", ou chamar sayHello.alternate() para output "hi". Mesmo assim, alternate() é um método público do escopo da função sayHello(), não um método estático.

Palavra-chave this

Função do this

Um dos conceitos mais importantes a serem compreendidos no ECMAScript é a utilização da palavra-chave this, que é usada em métodos de objetos. A palavra-chave this sempre aponta para o objeto que invoca o método, por exemplo:

var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(this.color);
};
oCar.showColor(); // saída "red"

TIY

No código acima, a palavra-chave this é usada no método showColor() do objeto. Neste ambiente, this é igual a oCar. O seguinte código tem a mesma função que o anterior:

var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(oCar.color);
};
oCar.showColor(); // saída "red"

TIY

Razões para usar this

Por que usar this? Porque, ao instanciar um objeto, nunca se pode determinar qual nome de variável o desenvolvedor usará. Usando this, é possível reutilizar a mesma função em vários lugares. Pense na seguinte exemplo:

function showColor() {
  alert(this.color);
};
var oCar1 = new Object;
oCar1.color = "red";
oCar1.showColor = showColor;
var oCar2 = new Object;
oCar2.color = "blue";
oCar2.showColor = showColor;
oCar1.showColor();		//saída "red"
oCar2.showColor();		//saída "blue"

TIY

No código acima, primeiro define a função showColor() usando this, então cria dois objetos (oCar1 e oCar2), onde a propriedade color do primeiro objeto é definida como "red" e a propriedade color do segundo objeto é definida como "blue". Ambos os objetos têm a propriedade showColor, que aponta para a função showColor () original (não há problema de nomeação aqui, pois um é uma função global e o outro é uma propriedade do objeto). Chamar showColor() de cada objeto, a saída do oCar1 é "red" e a saída do oCar2 é "blue". Isso ocorre porque, ao chamar o oCar1.showColor(), a palavra-chave this dentro da função é igual ao oCar1. Ao chamar o oCar2.showColor(), a palavra-chave this dentro da função é igual ao oCar2.

Atenção, ao referenciar propriedades de um objeto, é necessário usar a palavra-chave this. Por exemplo, se usar o seguinte código, o método showColor() não funcionará:

function showColor() {
  alert(color);
};

Se não usar o objeto ou a palavra-chave this para referenciar a variável, o ECMAScript o considerará uma variável local ou global. Em seguida, a função procurará uma variável local ou global chamada color, mas não a encontrará. E o resultado? A função mostrará "null" no aviso.