Ir para conteúdo

Como o Javascript conta a quantidade de elementos em um array?


Kevin Almeida

Posts Recomendados

  • Apoiador Nibble

me tirem uma pergunta que ta comendo o meu juizo a uns dias
nessa semana, vi o merces falar em uma aula de C que a quantidade de elementos em um array é dada pegando o tamanho do array e divindo pelo tamanho em bytes dos elementos, algo como  sizeof(array) / sizeof(typeOfElements), o que faz total sentido, se é um array de inteiros vc sabe que a memoria é alocada de 4 em 4 bytes para cada elemento, mas e no javascript? que a gente consegue fazer uma sopa dentro do array com varios tipos? como eles fazem isso? como que o runtime sabe que aquele byte especifico é um novo elemento e nao a continuacao do anterior?
sai internet afora procurando como funciona a estrutura de arrays por baixo dos panos na internet mas sem sucesso
alguem sabe algum artigo ou algum material que possa me dar uma luz pra essa questao?

  • l33t 1
Link para o comentário
Compartilhar em outros sites

Que pergunta boa. ?

Eu só consigo responder de forma leviana pois tenho zero experiência na programação de compiladores, engines, etc. O que sei é que em JavaScript os arrays são objetos, logo, não são simplesmente tipos primitivos em sequência na memória como em C.

Agora a parte que eu acho (por não conhecer os internals do JavaScript):

Quando você declara um array em JS, você está criando um objeto (alocando memória para ele) da classe Array. Portanto, provavelmente quando você coloca nele algum elemento, você tá na real chamando um método dessa classe. A diferença é que o programador faz isso sem ver. Por exemplo:

frutas = ['melão', 'maçã']

O código acima cria um objeto, uma instância da classe Array.  Acredito que seja equivalente ao seguinte (passando os elementos para o método construtor):

frutas = Array('melão', 'maçã')

Poderia também usar o método push:

frutas = Array()
frutas.push('melão')
frutas.push('maçã')

No entanto, é mais comum utilizar a notação como no primeiro código, o que pode dar a ilusão de que o array é similar ao do C, mas não é.

Em todos os casos, se você fizer typeof(frutas), vai ver que o retorno é object. Agora, os detalhes internos dessa implementação eu não faço ideia - e também imagino que depende do engine usado, porque poderia ser feito de diferentes maneiras, com diferentes estruturas de dados (listas encadeadas, hashmaps, etc) para armazenar o endereço dos tipos primitivos e objetos que são elementos do array.

Aqui tem detalhes da classe Array, mas ainda não responde sua dúvida. Recomendaria você:

  1. Implementar, em C, um tipo Array que suporte push e pop de elementos. Pode ser só do tipo int ou só do tipo char* pra ficar mais legal. Você pode usar ponteiro para funções para simular os métodos.
  2. Buscar o código-fonte de algum engine de JavaScript pra ver como eles fazem. Certamente vai ser diferente de como você fez, mas o fato de você ter feito o seu próprio "gerenciador de arrays" vai te dar uma solidez no assunto, mesmo que você escolha caminhos pouco otimizados e tal.

Isso pelo menos seria o que eu faria se eu quisesse entender isso profundamente, mas pode ser que alguém com conhecimento no assunto ajude mais aqui.

De qualquer forma, adoraria ver aqui o teu progresso neste estudo, para todos podermos aprender contigo. ?

Um abraço e boa sorte!

  • Agradecer 1
Link para o comentário
Compartilhar em outros sites

  • 8 meses depois...
  • Apoiador Nibble
On 9/27/2022 at 8:37 AM, Fernando Mercês said:

Que pergunta boa. ?

Eu só consigo responder de forma leviana pois tenho zero experiência na programação de compiladores, engines, etc. O que sei é que em JavaScript os arrays são objetos, logo, não são simplesmente tipos primitivos em sequência na memória como em C.

Agora a parte que eu acho (por não conhecer os internals do JavaScript):

Quando você declara um array em JS, você está criando um objeto (alocando memória para ele) da classe Array. Portanto, provavelmente quando você coloca nele algum elemento, você tá na real chamando um método dessa classe. A diferença é que o programador faz isso sem ver. Por exemplo:

frutas = ['melão', 'maçã']

O código acima cria um objeto, uma instância da classe Array.  Acredito que seja equivalente ao seguinte (passando os elementos para o método construtor):

frutas = Array('melão', 'maçã')

Poderia também usar o método push:

frutas = Array()
frutas.push('melão')
frutas.push('maçã')

No entanto, é mais comum utilizar a notação como no primeiro código, o que pode dar a ilusão de que o array é similar ao do C, mas não é.

Em todos os casos, se você fizer typeof(frutas), vai ver que o retorno é object. Agora, os detalhes internos dessa implementação eu não faço ideia - e também imagino que depende do engine usado, porque poderia ser feito de diferentes maneiras, com diferentes estruturas de dados (listas encadeadas, hashmaps, etc) para armazenar o endereço dos tipos primitivos e objetos que são elementos do array.

Aqui tem detalhes da classe Array, mas ainda não responde sua dúvida. Recomendaria você:

  1. Implementar, em C, um tipo Array que suporte push e pop de elementos. Pode ser só do tipo int ou só do tipo char* pra ficar mais legal. Você pode usar ponteiro para funções para simular os métodos.
  2. Buscar o código-fonte de algum engine de JavaScript pra ver como eles fazem. Certamente vai ser diferente de como você fez, mas o fato de você ter feito o seu próprio "gerenciador de arrays" vai te dar uma solidez no assunto, mesmo que você escolha caminhos pouco otimizados e tal.

Isso pelo menos seria o que eu faria se eu quisesse entender isso profundamente, mas pode ser que alguém com conhecimento no assunto ajude mais aqui.

De qualquer forma, adoraria ver aqui o teu progresso neste estudo, para todos podermos aprender contigo. ?

Um abraço e boa sorte!

Bom, depois de muito tempo eu voltei aqui para dizer que a explicação é a mais simples possível! haha
Dentro do objeto Array em javascript temos um atributo chamado length que é incrementado e decrementado conforme utilizamos funções como pop() ou push(), caso o array seja criado vazio, este atributo inicia como zero, se não, ele inicia com o numero de argumentos passados no new Array(), seja ele convertido de um [] ou não.
o que eu achei bastante interessante foi saber que para a alocação de memória inicial de um array cada engine de javascript utiliza um método interno próprio de quanta memória alocar, no NodeJs o V8 usa uma estratégia chamada ElementsKind que resumidamente define o tipo de cada elemento e quanto de memória vai ser alocada, e caso o array cresça ele utiliza uma "estratégia de realocação incremental", cria-se um bloco de memória com uma maior capacidade e se copia os elementos para ele, tudo gerenciado pelo engine, claro.

e eu pensando que era algum super cálculo complexo 😕

Link para o comentário
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...