The Codest
  • Sobre nós
  • Serviços
    • Desenvolvimento de software
      • Desenvolvimento de front-end
      • Desenvolvimento backend
    • Staff Augmentation
      • Programadores Frontend
      • Programadores de back-end
      • Engenheiros de dados
      • Engenheiros de nuvem
      • Engenheiros de GQ
      • Outros
    • Aconselhamento
      • Auditoria e consultoria
  • Indústrias
    • Fintech e Banca
    • E-commerce
    • Adtech
    • Tecnologia da saúde
    • Fabrico
    • Logística
    • Automóvel
    • IOT
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • A nossa equipa
  • Case Studies
  • Saber como
    • Blogue
    • Encontros
    • Webinars
    • Recursos
Carreiras Entrar em contacto
  • Sobre nós
  • Serviços
    • Desenvolvimento de software
      • Desenvolvimento de front-end
      • Desenvolvimento backend
    • Staff Augmentation
      • Programadores Frontend
      • Programadores de back-end
      • Engenheiros de dados
      • Engenheiros de nuvem
      • Engenheiros de GQ
      • Outros
    • Aconselhamento
      • Auditoria e consultoria
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • A nossa equipa
  • Case Studies
  • Saber como
    • Blogue
    • Encontros
    • Webinars
    • Recursos
Carreiras Entrar em contacto
Seta para trás VOLTAR
2020-10-13
Desenvolvimento de software

O poder dos objectos JavaScript

The Codest

Bartosz Slysz

Software Engineer

Os últimos anos mostraram-nos que o desenvolvimento Web está a mudar. À medida que muitas funcionalidades e APIs foram sendo adicionadas aos browsers, tivemos de as utilizar da forma correta. A linguagem a que devemos esta honra foi a JavaScript.

Inicialmente, os programadores não estavam convencidos da forma como foi concebido e tiveram, na sua maioria, impressões negativas ao utilizarem este script. Com o tempo, verificou-se que esta linguagem tem um grande potencial e as normas ECMAScript subsequentes tornaram alguns dos mecanismos mais humanos e, simplesmente, melhores. Neste artigo, damos uma vista de olhos a algumas delas.

Tipos de valores em JS

A verdade bem conhecida sobre JavaScript é que tudo aqui é um objeto. A sério, tudo: matrizes, funções, cadeias de caracteres, números e até booleanos. Todos os tipos de valores são representados por objectos e têm os seus próprios métodos e campos. No entanto, podemos dividi-los em duas categorias: primitivos e estruturais. Os valores da primeira categoria são imutáveis, o que significa que podemos reatribuir uma variável com um novo valor, mas não podemos modificar o valor existente. A segunda representa valores que podem ser alterados, pelo que devem ser interpretados como colecções de propriedades que podemos substituir ou simplesmente chamar os métodos concebidos para o fazer. 

Âmbito das variáveis declaradas

Antes de nos aprofundarmos, vamos explicar o que significa o âmbito. Podemos dizer que o âmbito é a única área onde podemos utilizar as variáveis declaradas. Antes do padrão ES6, podíamos declarar variáveis com a instrução var e dar a elas escopo global ou local. O primeiro é um domínio que permite nós para aceder a algumas variáveis em qualquer local da aplicação, o segundo é apenas dedicado a uma área específica - principalmente uma função.

Desde a norma ES2015, JavaScript tem três maneiras de declarar variáveis que diferem com a palavra-chave. A primeira é descrita anteriormente: as variáveis declaradas pela palavra-chave var têm o âmbito do corpo da função atual. A norma ES6 permitiu-nos declarar variáveis de formas mais humanas - ao contrário das declarações var, as variáveis declaradas pelas declarações const e let têm apenas o âmbito do bloco. No entanto, o JS trata a declaração const de forma bastante invulgar se comparada com outras declarações linguagens de programação - em vez de um valor persistente, mantém uma referência persistente para o valor. Em suma, podemos modificar as propriedades de um objeto declarado com uma declaração const, mas não podemos substituir a referência desta variável. Há quem diga que a alternativa var no ES6 é, na verdade, uma declaração let. Não, não é, e a declaração var não é e provavelmente nunca será retirada. Uma boa prática é evitar a utilização de declarações var, porque a maior parte das vezes dão-nos mais problemas. Por sua vez, temos de abusar das declarações const, até termos de modificar a sua referência - então devemos usar let. 

Exemplo de comportamento inesperado do âmbito

Comecemos pelo seguinte código: 

(() => {
 for (var i = 0; i  {
      console.log(`Valor de "i": ${i}`);
    }, 1000);
  }
})();

Quando olhamos para ele, parece que o loop for itera o valor i e, após um segundo, regista os valores do iterador: 1, 2, 3, 4, 5. Bem, isso não acontece. Como mencionámos acima, a instrução var tem como objetivo manter o valor de uma variável durante todo o corpo da função; isto significa que na segunda, terceira e assim sucessivamente, o valor da variável i será substituído por um valor seguinte. Finalmente, o ciclo termina e os ticks de timeout mostram-nos o seguinte: 5, 5, 5, 5, 5, 5. A melhor forma de manter um valor atual do iterador é utilizar a instrução let:

(() => {
 for (let i = 0; i  {
      console.log(`Valor de "i": ${i}`);
    }, 1000);
  }
})();

No exemplo acima, mantemos o âmbito do valor i no bloco de iteração atual, é o único domínio onde podemos utilizar esta variável e nada a pode substituir fora desta área. O resultado neste caso é o esperado: 1 2 3 4 5. Vamos ver como lidar com esta situação com uma declaração var: 

(() => {
 for (var i = 0; i  {
      setTimeout(() => {
        console.log(`Valor de "j": ${j}`);
      }, 1000);
    })(i);
  }
})();

Uma vez que a declaração var se destina a manter o valor dentro do bloco de funções, temos de chamar uma função definida que recebe um argumento - o valor do estado atual do iterador - e depois fazer algo. Nada fora da função declarada irá sobrepor-se ao valor j. 

Exemplos de expectativas erradas de valores de objectos

O crime mais frequente que notei diz respeito a ignorar o poder das estruturas e alterar as suas propriedades que também são modificadas noutras partes do código. Dê uma olhadela rápida: 

const DEFAULT_VALUE = {
  favoriteBand: 'The Weeknd'
};
const currentValue = DEFAULT_VALUE;
const bandInput = document.querySelector('#favorite-band');
const restoreDefaultButton = document.querySelector('#restore-button');
bandInput.addEventListener('input', () => {
  currentValue.favoriteBand = bandInput.value;
}, false);
restoreDefaultButton.addEventListener('click', () => {
  currentValue = DEFAULT_VALUE;
}, false);

Desde o início: vamos assumir que temos um modelo com propriedades predefinidas, armazenadas como um objeto. Queremos ter um botão que restaure os valores de entrada para os valores predefinidos. Depois de preencher a entrada com alguns valores, actualizamos o modelo. Passado um momento, pensamos que a escolha por defeito era simplesmente melhor, por isso queremos restaurá-la. Clicamos no botão... e nada acontece. Porquê? Porque ignoramos o poder dos valores referenciados. 

Esta parte: const currentValue = DEFAULTVALUE está a dizer ao JS o seguinte: pegue na referência para a variável DEFAULTVALUE e atribui a variável currentValue a esse valor. O valor real é armazenado na memória apenas uma vez e ambas as variáveis estão a apontar para ele. Modificar algumas propriedades num local significa modificá-las noutro. Temos algumas formas de evitar situações como esta. Uma que satisfaz as nossas necessidades é um operador de propagação. Vamos corrigir o nosso código:

const DEFAULT_VALUE = {
  favoriteBand: 'The Weeknd'
};
const currentValue = { ...DEFAULT_VALUE };
const bandInput = document.querySelector('#favorite-band');
const restoreDefaultButton = document.querySelector('#restore-button');
bandInput.addEventListener('input', () => {
  currentValue.favoriteBand = bandInput.value;
}, false);
restoreDefaultButton.addEventListener('click', () => {
  currentValue = { ...DEFAULT_VALUE };
}, false);

Neste caso, o operador de dispersão funciona da seguinte forma: pega em todas as propriedades de um objeto e cria um novo objeto preenchido com elas. Graças a isto, os valores em currentValue e DEFAULT_VALUE já não estão a apontar para o mesmo local na memória e todas as alterações aplicadas a um deles não afectarão os outros. 

Ok, então a questão é: trata-se apenas de utilizar o operador mágico de dispersão? Neste caso - sim, mas os nossos modelos podem exigir mais complexidade do que este exemplo. No caso de utilizarmos objectos aninhados, arrays ou quaisquer outras estruturas, o operador de dispersão do valor referenciado de nível superior só afectará o nível superior e as propriedades referenciadas continuarão a partilhar o mesmo lugar na memória. Há muitas soluções para lidar com este problema, tudo depende das suas necessidades. Podemos clonar objectos em todos os níveis de profundidade ou, em operações mais complexas, utilizar ferramentas como o immer, que nos permite escrever código imutável de forma quase indolor.

Misturar tudo

É possível utilizar uma mistura de conhecimentos sobre âmbitos de aplicação e tipos de valores? Claro que sim! Vamos construir algo que utilize ambos: 

 const useValue = (defaultValue) => {
 const value = [...defaultValue];
 const setValue = (newValue) => {
    value.length = 0; // maneira complicada de limpar o array
    newValue.forEach((item, index) => {
      value[index] = item;
    });
 // faz algumas outras coisas
  };

 retorna [valor, setValue];
};
const [animals, setAnimals] = useValue(['cat', 'dog']);
console.log(animals); // ['cat', 'dog']
setAnimals(['horse', 'cow']);
consola.log(animais); // ['cavalo', 'vaca']);

Vamos explicar como este código funciona linha a linha. Bem, a função useValue está a criar uma matriz com base no argumento defaultValue; cria uma variável e outra função, o seu modificador. Este modificador recebe um novo valor que é, de uma forma complicada, aplicado ao valor existente. No final da função, devolvemos o valor e o seu modificador como valores da matriz. De seguida, utilizamos a função criada - declaramos animais e setAnimals como valores devolvidos. Utilize o seu modificador para verificar se a função afecta a variável animal - sim, funciona! 

Mas espere, o que é que este código tem de especial? A referência mantém todos os novos valores e pode injetar a sua própria lógica neste modificador, como por exemplo algumas APIs ou uma parte do ecossistema que alimenta seu fluxo de dados sem nenhum esforço. Esse padrão complicado é frequentemente usado em bibliotecas JS mais modernas, onde o paradigma funcional na programação nos permite manter o código menos complexo e mais fácil de ler por outros programadores. 

Resumo

A compreensão de como a mecânica da linguagem funciona nos bastidores permite-nos escrever código mais consciente e leve. Mesmo que JS não seja uma linguagem de baixo nível e nos obrigue a ter algum conhecimento sobre como a memória é atribuída e armazenada, ainda temos de estar atentos a comportamentos inesperados quando modificamos objectos. Por outro lado, abusar de clones de valores nem sempre é o caminho certo e a utilização incorrecta tem mais contras do que vantagens. A forma correta de planear o fluxo de dados é considerar o que precisa e os possíveis obstáculos que pode encontrar ao implementar a lógica da aplicação.

Ler mais:

  • Como melhorar as aplicações Vue.js? Algumas dicas práticas
  • Caraterísticas do Vuex que deve conhecer se realmente se preocupa com a sua loja
  • Como escrever um código bom e de qualidade?

Artigos relacionados

Ilustração de uma aplicação de cuidados de saúde para smartphone com um ícone de coração e um gráfico de saúde em ascensão, com o logótipo The Codest, representando soluções digitais de saúde e HealthTech.
Desenvolvimento de software

Softwares para o setor de saúde: Tipos, casos de uso

As ferramentas em que as organizações de cuidados de saúde confiam atualmente não se assemelham em nada às fichas de papel de há décadas atrás. O software de cuidados de saúde apoia agora os sistemas de saúde, os cuidados aos doentes e a prestação de cuidados de saúde modernos em...

OCODEST
Ilustração abstrata de um gráfico de barras em declínio com uma seta ascendente e uma moeda de ouro que simboliza a eficiência ou a poupança de custos. O logótipo The Codest aparece no canto superior esquerdo com o slogan "In Code We Trust" sobre um fundo cinzento claro
Desenvolvimento de software

Como dimensionar a sua equipa de desenvolvimento sem perder a qualidade do produto

Aumentar a sua equipa de desenvolvimento? Saiba como crescer sem sacrificar a qualidade do produto. Este guia cobre sinais de que é hora de escalar, estrutura da equipe, contratação, liderança e ferramentas - além de como o The Codest pode...

OCODEST
Desenvolvimento de software

Construir aplicações Web preparadas para o futuro: ideias da equipa de especialistas do The Codest

Descubra como o The Codest se destaca na criação de aplicações web escaláveis e interactivas com tecnologias de ponta, proporcionando experiências de utilizador perfeitas em todas as plataformas. Saiba como a nossa experiência impulsiona a transformação digital e o negócio...

OCODEST
Desenvolvimento de software

As 10 principais empresas de desenvolvimento de software sediadas na Letónia

Saiba mais sobre as principais empresas de desenvolvimento de software da Letónia e as suas soluções inovadoras no nosso último artigo. Descubra como estes líderes tecnológicos podem ajudar a elevar o seu negócio.

thecodest
Soluções para empresas e escalas

Fundamentos do desenvolvimento de software Java: Um Guia para Terceirizar com Sucesso

Explore este guia essencial sobre o desenvolvimento de software Java outsourcing com sucesso para aumentar a eficiência, aceder a conhecimentos especializados e impulsionar o sucesso do projeto com The Codest.

thecodest

Subscreva a nossa base de conhecimentos e mantenha-se atualizado sobre os conhecimentos do sector das TI.

    Sobre nós

    The Codest - Empresa internacional de desenvolvimento de software com centros tecnológicos na Polónia.

    Reino Unido - Sede

    • Office 303B, 182-184 High Street North E6 2JA
      Londres, Inglaterra

    Polónia - Pólos tecnológicos locais

    • Parque de escritórios Fabryczna, Aleja
      Pokoju 18, 31-564 Cracóvia
    • Embaixada do Cérebro, Konstruktorska
      11, 02-673 Varsóvia, Polónia

      The Codest

    • Início
    • Sobre nós
    • Serviços
    • Case Studies
    • Saber como
    • Carreiras
    • Dicionário

      Serviços

    • Aconselhamento
    • Desenvolvimento de software
    • Desenvolvimento backend
    • Desenvolvimento de front-end
    • Staff Augmentation
    • Programadores de back-end
    • Engenheiros de nuvem
    • Engenheiros de dados
    • Outros
    • Engenheiros de GQ

      Recursos

    • Factos e mitos sobre a cooperação com um parceiro externo de desenvolvimento de software
    • Dos EUA para a Europa: Porque é que as empresas americanas decidem mudar-se para a Europa?
    • Comparação dos centros de desenvolvimento da Tech Offshore: Tech Offshore Europa (Polónia), ASEAN (Filipinas), Eurásia (Turquia)
    • Quais são os principais desafios dos CTOs e dos CIOs?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Direitos de autor © 2026 por The Codest. Todos os direitos reservados.

    pt_PTPortuguese
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek cs_CZCzech pt_PTPortuguese