Solucionado: Criar o método .shift()
5
0

Solucionado: Criar o método .shift()

Como é a função shift do JavaScript? Analisamos como funciona memória e ponteiros no JavaScript para replicar um método tão famoso com arrays

Gabriel e Pedro
5 min
5
0

👋 Opa, Gabriel e Pedro aqui e seja bem-vindo para mais um episódio da nossa newsletter semanal, a Challenge House. Toda quinta-feira, temos a solução de um desafio JavaScript que foi divulgado no início da semana.

Vem com a gente que lá vem história e já inscreva no nosso canal para não perder o próximo 👇

Seguir meu Canal

🏠 Challenge House sendo desvendada

Email image

No início da semana, compartilhamos o desafio para criar o método .shift()

Sem mais demora, a solução em formato de código é essa aqui:

let list = ["👩🏽‍🚀", "😱", "🚀"];
const shift = (listToBeWorked) => {
const [firstItem, ...newArrayWithoutFirstItem] = listToBeWorked;
for(let i = 0; i < listToBeWorked.length ; i++){
listToBeWorked[i] = newArrayWithoutFirstItem[i];
}
listToBeWorked.length = listToBeWorked.length - 1;
return firstItem;
};
let result = shift(list);
console.log(result);
console.log(list);

🌀 Ao vivo e à cores

Não acredita que o código ali em cima funciona? Criamos uma execução dele no CodePen para você poder ver de perto. Basta rodar 👇


🤓 Por que na minha máquina funciona?

Não adianta viver de CTRL + C e CTRL + Z. É preciso entender o motivo daquele código rodar da forma correta. Vamos lá?

Temos muito a aprender com esse desafio e, por isso, separamos a explicação por alguns tópicos:

1 - Todo Array em Javascript é um Objeto.

Isso é primordial para o seu dia a dia na programação com JavaScript.

Quase todos os tipos de variáveis sempre são convertidos em Objetos que guardam, além do valor da variável, vários métodos e dados que facilitam a sua manutenção.

Sendo assim, podemos dizer que uma lista é convertida em um objeto que possuí métodos únicos para lidar com aquele tipo de dado.

2 - Objetos em Javascript tem Prototypes. 

Se você não conhece o conceito de Prototypes, recomendamos, fortemente, que você leia esse artigo da MDN:

Prototypes são propriedades que serão compartilhadas entre Objetos. Todo Array é um objeto e compartilha propriedades. Como, por exemplo, a propriedade length que guarda em si o tamanho que o Array possui.

3 - As propriedades podem ser alteradas.

Acabamos de dizer que a propriedade length é acessível em um array e retorna seu o tamanho.

Além disso, o length também é responsável por controlar o número de elementos que um array possui. Ao usar a manipulação dessa propriedade, conseguimos mudar o tamanho do array, que originalmente seria de 3, para 2.

4 - Os valores de um Array são propriedades do Objeto criado.

Aqui encontramos algo confuso. Porém, o entendimento é extremamente importante para um desenvolvedor JavaScript.

Veja o exemplo do tratamento de um objeto simples:

let objetoUm = { name: "Gabriel" };
let cloneDoObjetoUm = objetoUm;
cloneDoObjetoUm["name"] = "Pedro";
console.log(objetoUm);
console.log(cloneDoObjetoUm);

No exemplo acima, criamos um objeto e logo depois criamos um segundo objeto utilizando como base o primeiro. Um clone.

O que acontece é que as PROPRIEDADES de um objeto em javascript são registradas como um endereço na memória que guarda um valor.

Quando criamos uma propriedade e damos um nome a ela, estamos separando um lugar na memória do seu computador para guardar aquele valor.

Quando clonamos o primeiro objeto, embora tenhamos criado um novo objeto, aquilo que está dentro do primeiro objeto (endereços para acessarmos valores das propriedades) é usado.

Se alteramos o valor no segundo objeto de uma propriedade, também alteramos o valor no primeiro objeto. Isso ocorre, porque quando acessamos a propriedade daquele objeto para mudar o valor, acessamos, na verdade, o endereço da memória daquela propriedade.

Sim, é confuso… Para os programadores que vem do C, Java e outras linguagens é fácil entender que propriedades são ponteiros. Caixas que possuem um endereço de acesso a valores.

Voltando a nossa resolução, uma importante funcionalidade do .shift() é que ele altera o array original. É usando essa dinâmica de acessar os endereços da memória para alterar os valores que usamos o loop for.

 Veja:

const shift = (listToBeWorked) => {
const [firstItem, ...newArrayWithoutFirstItem] = listToBeWorked;
for(let i = 0; i < listToBeWorked.length ; i++){
listToBeWorked[i] = newArrayWithoutFirstItem[i];
}
listToBeWorked.length = newArrayWithoutFirstItem.length;
return firstItem;
};

Quando criamos nossa função shift, ela passou a receber como parâmetro listToBeWorked.

Passamos a nossa lista para ser guardada no escopo dessa função dentro da variável listToBeWorked.

Tal qual no exemplos dos dois objetos, o que estamos fazendo é clonando o nosso objeto inicial dentro de uma nova variável. Apesar de ser uma nova variável, por ser um clone, guarda os endereços de memória daquele objeto (list) inicial.

Dessa forma, elas passam a compartilhar mudanças, tipo o Vecna e os Demorgorgons em Stranger Things.

Por isso, fazemos um loop, no qual acessamos cada um das propriedades do array, que são os seus items da lista, e mudamos o valor.

Como o valor é guardado no mesmo endereço de memória, estamos alterando o valor do nosso array inicial.

Para ir ainda mais a fundo nesse tema, eu recomendo os seguintes artigos:

🥸 Sim, existem outras formas de resolver esse desafio:

let list = ["👩", "😱", "🚀"];
const shift = (listToBeWorked) => {
let firstItem = listToBeWorked[0];
listToBeWorked.splice(0,1);
return firstItem;
};
let result = shift(list);
console.log(result);
console.log(list);

No código acima, utilizamos um outro método de Objetos tipo array para lidar com a deleção do primeiro item. O método .splice().

Leia o seguinte artigo para conhecer mais sobre essa propriedade:

O importante nesse segundo exemplo é entendermos que ele funciona, pois o .splice() da list (array original) e de listToBeWorked (array que será usado na função) são exatamente os mesmos, uma vez que propriedades são endereços de memória para um valor.

O valor nesse caso é um método. Toda vez esse método executa sob os endereços de memória que foram clonados, alterando ,portanto, ambos os Objetos Arrays.

Apesar de ser um código mais limpo, ele só é mais simples, porque entendemos como funcionam Array, Objeto e propriedades no JavaScript 🙂

Se você pensou de outra maneira e fez o um código diferente, iríamos adorar saber a solução também. Sinta-se a vontade para chamar a gente no instagram da Challenge House ou responder por email esta newsletter.


Se você achou o conteúdo dessa newsletter interessante, pense com carinho em fazer alguma dessas coisas:

1. ❤️ Compartilhar com os amigos - é com a sua ajuda que iremos levar o Challenge House para cada vez mais pessoas.

Compartilhar conteúdo

2. ✉️ Se inscrever na nossa newsletter - se ainda não é, iremos ficar muito felizes com a sua inscrição.

Seguir meu Canal

Até segunda-feira,

Gabriel e Pedro 👋