Executando verificação de segurança...
1

Dúvida sobre o objeto variável, pilha e heap no Javascript

Pessoal, lendo o livro Princípios de Orientação a Objetos em Javascript do Nicholas Zakas surgiu uma dúvida sobre termo "OBJETO VARIÁVEL" do Javascript. Segue o trecho:

Outras linguagens de programação distinguem os tipos armazenado os PRIMITIVOS na PILHA e os de REFERÊNCIA no HEAP. O Javascript não utiliza este conceito, ele controla as variáveis de um escopo em particular, usando um OBJETO VARIÁVEL.

Valores primitivos são armazenados diretamente no OBJETO VARIÁVEL e os valores de referência são criados como ponteiros no OBJETO VARIÁVEL.

Procurei mais na internet sobre o OBJETO VARIÁVEL para tentar entender melhor como funciona, mas não encontrei nenhuma explicação. Então, pelo que entendi:

Cada escopo do JS tem um OBJETO que armazena os tipos primitivos e os ponteiros dos tipos de referência. Então NÃO existe uma pilha com os primitivos e os de referência são armazenados no heap com o ponteiro no objeto. É isso mesmo?

Valeu...

Carregando publicação patrocinada...
3

Esses termos são bastante controversos. Não deveria, estão falando de ciência, mas acabou que na nossa área o "mercado" resolveu que ciência não importa muito e cada um tem sua própria opinião sobre certos termos. Muita informação, até mesmo em livros, é errada, ou pelo menos ruim. Tenha isso em mente. E isso é complicado porque quando a pessoa aprende errado ela treina o erro e passa tratar aquilo como certo. Acontece muito mais do imagina. E possivelmente, dependendo da personalidade, vai brigar com quem falar o certo para você no futuro. Tome cuidado.

Primitivo por exemplo, é um termo que ninguém sabe bem o que é, e cada tecnologia adota uma definição diferente. E até mesmo autores falando da mesma tecnologia adota algo diferente. Eu espero que a definição dada pelo livro esteja correta, não vou procurar especificamente sobre JavaScript. Provavelmente primitivo seja tipos por valor, nessa definição.

Já tem um erro em alguma definição porque objetos por valor (ou primitivos como estão sendo usados) podem estar no heap. Se ele está dentro de um objeto por referência, ele está no heap, isso inclui arrays por exemplo. Então já entenda que o livro parece uma referência ruim, se não tiver um contexto maior explicando isso. Pelo menos não errou falando de JS que é o foco do livro.

O termo "objeto variável" estou vendo pela primeira vez. Não sei se é tradução ruim, invenção do autor ou outra coisa. Provavelmente por isso não achou nada.

Outras linguagens

Os objetos por valor armazenam seu valor no local da variável, ou seja, não há uma indireção na variável para indicar onde o objeto está, ou seja, não há uma referência.

Objetos por referência possuem um ponteiro como seu valor básico. Esse é o valor que está na variável, mas o valor que interessa ao seu código está em outro lugar, apontado justamente por esse ponteiro.

Existem variáveis locais cujo escopo é só a função ou até mesmo uma parte da função (stack frame (útil)). Então há reserva de espaço para todas as variáveis daquele escopo e lá os objetos serão armazenados. Isso é a stack, que é uma pilha como o nome já diz (pode ajudar).

Pode chamar esse stack frame de objeto? Pode, não é um objeto do seu código, acho que é fácil confundir usando esse termo, então eu não chamaria, melhor usar o termo mais específico. Aliás, em geral as pessoas não entendem bem o que é um objeto.

Alguns objetos por serem por referência armazenam ponteiros ali e o objeto real vai para o heap. Dentro desses objetos podem ter outras variáveis. Variável é um conceito de programação e não de execução de código.

JavaScript

Pelo que eu entendi, JavaScript coloca tudo no heap. Mas não sei se isso é especificado pela linguagem. Pode ser só como as implmentações mais conhecidas funcionam. E aí pode mudar. Eu não vejo muita razão para a linguagem obrigar ser assim.

Quando uma linguagem abre mão da pilha ela fica bem mais ineficiente porque precisa ficar alocando e desalocando os objetos no heap, que é absurdamente mais caro que na pilha. Mas JavaScript é uma linguagem de script, não foi criada para fazer nada que exija performance mesmo, então está ok.

Ou seja, em vez de organiar as variáveis de um escopo como uma pilha que é mais eficiente, a implmentação de JS prefere manter isso como objetos soltos, ou seja, mistura tudo, como um heap. A implmentação pode eventalmente separar esse heap do outro heap mais tradicional, mas não consigo enxergar muita vantagem.

Conclusão

Esse detalhe não é muito relevante para maioria dos programadores, especialmente em JS. Em C, C+, Rust, eventualmente em Java, C#, Go pode ser mais relevante em alguns casos. Eu não me preocuparia muito com isso enquanto estiver usando JS.

Então, para o que costuma ver implementado, é isso mesmo.

Como pode ver isso e muito mais eu já respondi no Stack Overflow. Se quiser pode pesquisar lá.

Farei algo que muitos pedem para aprender programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

2

A única referência que encontrei foi este artigo (referenciado nesta resposta do Stack Overflow), que menciona o termo "Variable Object" (talvez "Objeto Variável" não seja a melhor tradução, isso se livro estiver falando da mesma coisa).

Enfim, segundo o artigo:

A variable object is a scope of data related with the execution context. It’s a special object associated with the context and which stores variables and function declarations are being defined within the context.

A variable object is an abstract concept. In different context types, physically, it’s presented using different object.

[..] in the global context the variable object is the global object itself [..]

[..] a function’s variable object is the same simple variable object, but besides variables and function declarations, it also stores formal parameters and arguments object, and is called the activation object.

[..] when accessing this in a code, its value is taken directly from the execution context without any scope-chain lookup.

Ou seja:

Um objeto variável é um escopo de dados relacionados ao contexto de execução. É um objeto especial associado ao contexto, que guarda variáveis e funções definidas dentro deste contexto.

Um objeto variável é um conceito abstrato. Em diferentes contextos, fisicamente, é representado por um objeto diferente.

[..] no contexto global, o objeto variável é o próprio objeto global [..]

[..] um objeto variável de uma função é o mesmo objeto variável simples, mas além de variáveis e funções, também guarda parâmetros formais e argumentos, e é chamado de objeto de ativação.

[..] quando o this é acessado, seu valor é diretamente obtido do contexto de execução sem qualquer lookup na cadeia de escopos.

O artigo dá um exemplo criando uma variável e uma função no escopo global:

var foo = 10;
function bar() {} 

Com isso, o objeto variável referente ao contexto global seria algo assim:


Na versão atual da especificação da linguagem não há referência ao termo. O mais próximo que encontrei (que pela descrição parece ser bem similar ao descrito acima) é "VariableEnvironment".

1

Você acertou no seu entendimento!
JS realmente é diferente das outras linguagens!

Os tipos primitivos são imutaveis no javaScript