escher

Viagens do Javascript: Criação e manipulação de Objetos

Fala Pessoal,

Para o primeiro post técnico do blog, decidi começar com uma das maiores doideiras do javascript, na minha opinião. Que são algumas, das diversas formas de se criar e manipular objetos…

E nem precisa dizer (rapaziada do serviço que o diga) de que como eu repito que como o JS é um linguagem traiçoeira e requer muita disciplina…

Também, esse não é um artigo que visa cobrir todas as características das abordagens, mas levantar alguns pontos interessantes.

Objetos Literais

// Objeto Litral
var objLiteral = {
  prop1: "valor da prop 1",
  prop2: "valor da prop 2"
};

console.log(objLiteral.prop1) //valor da prop 1</pre>

Acho que o que podemos pensar de mais próximo de objetos estáticos das linguagens mais famosas.

É Tipo muito bacana para ser usado em configurações ou algo que precise de uma manuseio rápido, mas, organizado de uma estrutura de dados relativamente complexa, ou que possa crescer.

Ponto interessante é que eles não são instanciáveis. ou seja, não suportam a criação de novos objetos por sí só, com o new, por exemplo.

var a = new objLiteral(); // Erro...

Uma curiosidade, é que de maneira geral, plugins, como os do jQuery, adotam aos montes essa abordagem. Acredito porque ele desonera o construtor da função da declaração de muitos atributos. Já que o javascript não suporta Sobrecarga de Métodos

// https://api.jquery.com/jquery.ajax/
var config = {
  url: "test.html",
  context: document.body
}

$.ajax(config)

// Caso contrátio:
// Imagine o cenário, com todos os seus mais de 30 possíveis parâmetros:
// $.ajax(url, context, ... + 30) = caos

Injeção de propriedades

objLiteral.novaProp = "Born to be Wild!";

Não que isso não possa ser feito nas outras abordagens, mas, assim como tudo na vida, que tem seus pontos positivos e negativos, injeções de propriedade podem ser um conceito muito poderoso em nosso dia a dia.

E como já diria o tio Ben: “Com grandes poderes vem grandes responsabilidades”.

Mas, note que: O Tio Ben Morreu! Ou seja,  Tome muito cuidado com essa flexibilidade. Não saia por aí como um louco injetando propriedades em seus objetos só porque o próximo métodos precisou de mais uma propriedade. Pense sempre no ciclo de vida daquele objeto.

Uma dica pra facilitar é manter sua definição em um local fixo, e documentar suas propriedades…

// No arquivo, ou local fixo da definição:

/**
* Objeto que irá servir para fazer alguma coisa, em tais casos...
*/
var objLiteral = {
  /**
  * Propriedade que faz tal coisa...
  */
  prop1: "valor da prop 1",

  /**
  * Propriedade que faz outra coisa...
  */
  prop2: "valor da prop 2",

  /**
  * Propriedade que faz ainda outra coisa...
  */
  novaProp: "nova Propriedade"
};

// Na definição de um método que o consome:

/**
 * Método que vai fazer alguma coisa...
 * @parameter {objLiteral} configuracao Configuração para o objeto.
 */
function metodoTeste(configuracao) {
  //...
}

Contexto dentro do literal estático, usando operador de instancia.

Vamos dizer que você tenha uma função dentro do literal e queira fazer algum processamento com algum membro:

var objLiteral = {
    prop1: "valor da prop1",
    prop2: "valor da prop2",
    funcComContexto: function (valor) {
        this.prop1 = valor;
    }
};

objLiteral.funcComContexto("Classe 1");
console.log(objLiteral.prop1); // Classe 1

Doideiras à parte, o this, que é um operador de instância, funciona para referenciar o literal, mesmo ele não sendo uma “instancia” propriamente dita…

Objetos “Funcionais”

Funções são funções e PODEM ser objetos

Aqui o bicho pega…

Importante deixar claro que funções, são funções (claro), mas também podem assumir a figura de objetos instanciáveis.

function digaOla(mensagem) {
    return "Olá, " + mensagem;
}

function funcaoObjeto() {
    this.a = "variavel da função"
}

console.log(digaOla("José")) //Olá José;
console.log((new funcaoObjeto()).a) //"variavel da função" ;

Outra característica é de ser possível a declaração tendo em vista funções anonimas ou não.

// Função nomeadas
function objFuncional1() {
  //...
}

// Funções anônimas
var objFuncional2 = function () {
  //...
}

Que funções tem seu contexto, sem ser objetos instanciados…

function objFuncionalDelcarado(valor) {
    var antigo = this.propInterna;
    this.propInterna = valor;
    console.log(antigo, this.propInterna);
};

objFuncionalDelcarado("1"); // undefined '1'
objFuncionalDelcarado("2"); // 1 2
objFuncionalDelcarado("3"); // 2 3

Que variáveis podem ser definidas como propriedades dentro do construtor, como dentro do prototype (eu sei que existem diferenças, mas é só pra ilustrar).

// Declaração dentro da function.
function objFuncional1() {
  this.prop1 = "prop1";
};

// Declaração dentro do prototype.
function objFuncional2() { };
objFuncional2.prototype.prop1 = "prop1"

console.log(new objFuncional1().prop1)
console.log(new objFuncional2().prop1);

Que pode ter uma variável estática, declarada se injetando propriedades diretamente na definição da function…

function definicaoDoObjeto() {
    this.variavelDaInstancia = "variavel da instancia";
}

definicaoDoObjeto.varivalEstatica = "variavel Estatica";

console.log(definicaoDoObjeto.varivalEstatica) // variavel Estatica

Que existem variáveis de instância e de definição, e que as de definição, caso não sejam alteradas, se propagam para as instancias…

function definicaoDoObjeto() {
    this.variavelDaInstancia = "variavel da instancia";
};

definicaoDoObjeto.prototype.variavelDaDefinicao = "variavel da definicao";

var instancia1 = new definicaoDoObjeto();
var instancia2 = new definicaoDoObjeto();

instancia1.variavelDaInstancia = "novo valor";
instancia1.variavelDaDefinicao = "novo valor da variavel de definicao";

console.log(instancia1.variavelDaInstancia); // "novo valor";
console.log(instancia2.variavelDaInstancia); // "variavel da instancia"
console.log(instancia1.variavelDaDefinicao); // "novo valor da variavel de definicao"
console.log(instancia2.variavelDaDefinicao); // "variavel da definicao"

// Vamos alterar o valor da varável lá na definição do objeto...
definicaoDoObjeto.prototype.variavelDaDefinicao = "mudou";

console.log(instancia1.variavelDaDefinicao); // "novo valor da variavel de definicao (não mudou, pois já havia sido modificada...)"
console.log(instancia2.variavelDaDefinicao); // "mudou (foi alterada!)"

Enfim… Que se se você não definir padrões claros de trabalho, você e sua equipe vão ter que adicionar receitas de remédio tarja preta pro dia-a-dia da equipe…

Categories: Código, Javascript