- interpretada
- JIT (just-in-time) por causa da v8, tendo em vista as inumeras otimizações e melhorias de um interpretador normal
- first-class function (atribuir uma fn a um valor)
- não bloqueante
- concorrente
- baseado em prototipos
- tipagem dinamica
- multi paradigma (suporta POO, FP, imperativa, declarativa..)
- roda em diferentes ambientes (navegador, plataforma node...)
- sincrona
- single thread (workers threads(para node) e web workers(navegador) são técnicas para criar/manipular novas threads)
- event loop:
- é responsável pelo asincronismo
- pega do callback queue e colocar no callstack
- suportam paralelismo (clusters) cluster:
- fork/copias de processos (copia toda a sua stack/aplicação para um processo novo)
- motivação: tem uma máquina com recurso mt maior que a sua aplicação precisa, vc quer usar todos os cpus da máquina
cluster x thread:
- cluster é a copia do processo, então tem o seu próprio ambiente de execução e não compartilha memória entre os clusters, como a thread compartilha
as vendor APIS não fazem parte da linguagem javascript:
- DOM
- AJAX
- setTimeout
javascript possui várias engines, e todas elas são feitas em cima de uma especificação (ECMAScript) e não só as engines são baseadas nessa especificação, mas os supersets e linguagens que surgiram a partir do js
um super resumo da v8:
- interpreta o codigo fonte
- parsear
- executar
- controla uma pilha de execução(call stack) e a alotação de memória(memory heap)
- possui várias threas para: parser, cash, otimizações, garbage collector etc
contexto vs escopo: context:
- valor do 'this'
- this é atribuido a fn de forma dinamica, e não na hora da engine lendo/parseando o código, e sim qnd a fn é executada
- call, bind e apply
escopo:
- global ou local
- block: let/const (var n respeita)
- lexico: uma fn herda propriedades/tem acesso ao escopo de outra fn que contém ela.... ou seja, ela n consegue acessar o escopo de uma fn abaixo, ou de uma irma, só de uma fn pai
- limite aonde as expressões e valores são acessíveis
contexto de execução:
-
é o escopo (risos)
-
é um espaço dentro dessa fn que representa o escopo da fn
-
contem todos os valores que podem ser guardados em memoria/valores acessiveis: declaracoes de fn/variaveis
-
no caso de uma fn, ela apenas armazena(e não executa) TODA a fn na mémória, diferente de uma variável, aonde é armazaenada apenas o seu valor
-
existem dois tipos:
- o global (que pode ter vários contextos locais)
- e o local (no caso, o de uma fn)
-
funciona de maneira parecida com uma callstack, e após um contexto de execução local ser processado (retornar algo por exemplo), ele é destruído da memória pelo garbage collector
-
pode haver apenas um contexto global, mas vários contextos de execução dentro das fns
O contexto de execução possue 3 fases:
1 - fase de criação do obj do contexto:
- executa o hoisting ('levanta' as definições de fn e variáveis para o topo do contexto para chamar a fn antes msm de ser definida)
- coloca todos os valores (variaveis, fn) no obj de contexto
2 - criação do 'scope chain':
- no cenário de uma closure, ele terá o seu obj de contexto, mais os contextos das fn pai
- pelos motivos citados acima, ele é responsável pelo contexto lexico (closure != contexto lexico)
- ex: const executionContextObjt = { 'scopeChain': [{}, {}], 'localContextObj': {}, 'this': valuesOfThis }
3 - fase de execução:
- seta o valor de this (dinamicamente, como foi dito acima)
- quando o código é executado e empilhado na callstack