Bem-vindos à nossa comunidade!

Junte-se a nós e faça parte hoje mesmo!

Aula: "this" pode variar

Raquel

Membro
Cadastro
24/9/20
Postagens
153
Curtidas
157
Pontuação
100
O tal do this

É sempre uma pergunta recorrente né, mas o que diabos é esse this?

Gente, o this é complicado mesmo quando você chega do nada né MAS! estamos aqui para tirar essas dúvidas.

Eu sempre recomendo, quando alguém não entende o que é algum método ou função ou, nesse caso, variável no JavaScript - ou em qualquer linguagem de programação, diga-se de passagem - a minha sugestão é traduzir o nome dessa função, método ou variável.

O this, portanto, pode ser entendido como "isto" ou, ainda, "este" ou "esta". Faz ainda mais sentido quando se entende que o this se trata de contexto.

O this vai se referir ao contexto de um determinado bloco de código. É como se você estivesse falando "Aqui ó, é a este bloco de código que eu tô me referindo!"

Fora de qualquer bloco de código, o this vai se referir ao objeto global ("É isto aqui que eu tô me referindo agora!").

Dentro de uma função, o this vai depender de como esta função é chamada: numa chamada simples, que não está em modo estrito, o this não é definido pela chamada.

Já em modo estrito, o valor de this permanece seja qual for o definido ao entrar no contexto de execução.

As funções arrow não tem um this próprio, sendo o this definido lexicalmente, ou seja, seu valor é definido pelo contexto de execução onde está inserido.

JavaScript:
function Pessoa(){
  this.idade = 0;

  setInterval(() => {
    this.idade++; // |this| corretamente se refere ao objeto Pessoa
  }, 1000);
}

var p = new Pessoa();

Para funções, você poderia dizer "Ó, é esta função aqui que eu tô falando!"

Além disso, para ajudar ainda mais os estudos, recomendo esse vídeo super detalhado sobre a variável this.
 

mourabraz

Membro
Moderador
Cadastro
23/12/20
Postagens
101
Curtidas
151
Pontuação
100
Cidade
Leiria
Olá pessoal, gostaria de complementar o que a colega escreveu.

O "this" pode parecer complicado de fato, mas na verdade não é! Normalmente o que mais complica (principalmente para quem já programa com outras linguagens de programação como JAVA ou C#, C++ etc) é o uso das letras "t", "h", "i", "s" (juntas) porque nos remetem, ou nos levam a uma analogia errada com o que sabemos de outras linguagens de programação. Se no JS tivessem dado outro nome a "isto" o seu entendimento não seria tão complicado.

Minha sugestão para quem vem de outras linguagens de programação (daquelas que fazem o uso do "this") é que não tentem fazer uma analogia na tentativa de entender o que o "this" é no mundo JS.

Resumidamente o "this" é uma referência a alguma coisa que será determinada de forma dinâmica (e daí o seu poder) em tempo de execução. [originalmente estavam grifadas as palavras "em tempo de execução", mas resolvi tirar e ainda penso em remove-las por completo porque já é dito de forma dinâmica, ficou redundante!] O "this" só existe dentro de um contexto de execução (Global, Funções e Modules (module pattern)) e dentre as opções possíveis aquela que mais cria falsas percepções é o uso do this" dentro do contexto de execução de funções. Assim, para entender, ou prever, o valor do "this" é necessário conhecer quem é que está criando esse contexto de execução, por outras palavras, como está essa função sendo chamada (invocada, executada).

(Att: o this comporta-se de forma diferente quando se trata de uma Arrow Funtion. Mas a meu ver, se o entendimento do this for bem sedimentado, excluindo-se as Arrow Function do mundo JS, durante esse estudo, ficará muito mais fácil, tanto entender o this dentro como fora das Arrow Function.... spoiler - nas Arrow Funtions como não existe o this ele passa a se comportar como uma variável normal... ***)

Abaixo vou colocar um quadro resumo (que fiz há algum tempo, infelizmente não traduzi). E esse quadro resumo tem uma falha que é a de não abordar o valor do "this" dentro do "module pattern".



(*** - esta parte não é importante, por hora - se o this, dentro da Arrow Funtion, se comportar como uma variável normal, quer dizer que a sua visibilidade - escopo - será determinado durante a fase 1 do parse, e, protanto, estático, e caso não tenha sido definido o seu valor será "pesquisado" nas variaveis que ficaram closure durante a sua definição e assim em diante...)

A minha ideia era ser breve e poder partilhar esse quadro. Espero que ajude. Caso prefiram uma abordagem mais detalhada (mais extensa), por favor, não hesite em falar, este assunto do this não é simples para ser entendido de primeira, leva um tempo que é super normal.
Se preferirem o quadro traduzido me avisem também que posso trocar depois...


Abraços!
 

Attachments

  • the_this.jpg
    the_this.jpg
    76,4 KB · Visualizações: 22

Raquel

Membro
Cadastro
24/9/20
Postagens
153
Curtidas
157
Pontuação
100
Como posso simplificar um número para ele ficar no formato monetário de algum lugar específico?

Uma pergunta bem específica, mas como aconteceu algumas vezes recentemente, resolvi trazer algumas soluções de como fazer essa conversão!

A primeira delas é o objeto Intl.Number.format, que formata especificamente para formatos monetários de vários locais. Dependendo do local especificado, a String será impressa diferente:


JavaScript:
var numero = 123456.789

console.log(new Intl.NumberFormat().format(numero)) //sem especificar o local, ele tira pelo local do computador - se for Brasil, imprime 3.500

console.log(new Intl.NumberFormat('de-DE').format(numero)) //a divisão em alemão é igual à do Brasil, ponto para centenas e vírgula para os decimais

console.log(new Intl.NumberFormat('ar-EG').format(numero)) //em árabe, usa-se os dígitos árabes

console.log(new Intl.NumberFormat('en-IN').format(numero)) //a Índia usa separadores de milhares/cem mil/dez milhões

console.log(new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec').format(numero)) //A chave de extensão nu requer um sistema de numeração, ex. decimal chinês

Além dela, existe também o toLocaleString, que é um método que pode ser tanto do objeto Date (para conversão de datas), quanto para Number (para conversões monetárias):

JavaScript:
var numero = 3500;

console.log(numero.toLocaleString()) //imprime 3.500 - caso não seja informado o local, tal qual o NumberFormat

Os usos para conversão de números são muito parecidos com o do Number Format.

Já para conversão de datas:

JavaScript:
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0))

console.log(date.toLocaleString()) //também vai depender do local do computador, caso seja usado sem argumentos

console.log(date.toLocaleString('en-US')) //os EUA dividem as horas entre AM/PM para manhã e noite

console.log(date.toLocaleString('en-GB')) //no inglês britânico, as datas são dia-mês-ano e as horas são 24h, sem AM e PM

São métodos interessantes que tem os seus usos específicos em muito práticos!
 

Wivson Machado

Novo Membro
Cadastro
28/12/20
Postagens
8
Curtidas
10
Pontuação
19
Cidade
Niterói
Fala pessoal beleza?

Eu estou justamente nessa aula lá na Udemy e realmente o this a primeira vista é bem complexo... mas pegando carona na explicação da @Raquel vou colocar o meu entendimento sobre o this e gostaria de saber se estou com o entendimento correto.

o this nada mais é que um recurso para direcionar o contexto de um objeto ou função.

Exemplo: Eu posso ter uma variável "nome" no escopo global, dentro de um objeto ou dentro de uma função e quem vai ajudar a função a determinar qual das variáveis "nome" vai chamar é o this, estou correto?

JavaScript:
this.nome = 'Wivson' //Aqui estou usando o this para determinar a variável "nome" que será inserido no escopo global

let pessoa = {
    nome: 'Mário'  //Aqui defini a variável "nome" dentro do objeto pessoa(escopo local)
}

function pegarNome(){
    console.log(this.nome) //Função para pegar o resultado de uma variável "nome" independente do escopo que ela estiver
}

const imprimirNomeGlobal = pegarNome.bind(this) //O bind pede a referencia de onde o this da função vai pegar a variável "nome", nesse caso o this se refere ao escopo global
const imprimirNomeLocal = pegarNome.bind(pessoa) //O bind pede a referencia de onde o this da função vai pegar a variável "nome", nesse caso a referencia é o objeto "pessoa", a função "pegarNome" vai dentro do objeto pessoa e procura uma variável "nome"

imprimirNomeGlobal() //retorna Wivson
imprimirNomeLocal() //retorna Mário

Minha conclusão:
O recurso this permite que sejam criadas funções genéricas que podem acessar variáveis de nomes iguais em escopos diferentes apenas direcionando o escopo, fazendo o reaproveitamento da função bem melhor e tornando o código mais simples, uma vez que posso acessar variáveis de mesmo nome mesmo estando em escopos diferentes.

Bom, cheguei nessa conclusão depois de alguns dias quebrando a cabeça, vendo as aulas varias vezes e vídeos externos, gostaria muito de saber do fórum se essa minha conclusão está correta ou pelo menos no caminho correto.
 

mourabraz

Membro
Moderador
Cadastro
23/12/20
Postagens
101
Curtidas
151
Pontuação
100
Cidade
Leiria
@Wivson Machado olá tudo bem?


Gostaria de dar um conselho.

Não estudes o this junto com o estudo do escopo. Vai ajudar muito se você primeiro entender como funciona o escopo das variáveis para depois estudar como o this funciona.

Eu digo isto porque this e escopo são quase antagónicos. O escopo é léxico, isto quer dizer que está relacionado à forma como o código está escrito, a forma como o código está escrito é estático, depois de escrito já nada vai mudar esse código (não vale falar de transpiladores, compiladores e qualquer outra coisa, me refiro ao código final antes de ser usado por uma VM do javascript). Se o código não muda é então estático, poderíamos afirmar que o escopo, em javascript, que é léxico, é também, um escopo estático. Por outro lado, o this, é o mecanismo que torna as coisas dinâmicas (no que diz respeito a ter uma variável dinâmica, a variável, não o valor! - esta parte entre os parênteses se ficar confusa pula...).

O estudo do escopo é com o código escrito, o estudo do this é com a execução do código. Olhar para um código escrito, sem imaginar como ele se comportará na execução, não é suficiente para saber o que o this irá representar... hum representar e não valer....

Se quiser podemos falar mais sobre esta parte que escrevi aí em cima com mais detalhes.

Em relação ao que você escreveu, entendi que você escreveu certo 50%, mas acho que vale a pena tecer alguns comentários.

o this nada mais é que um recurso para direcionar o contexto de um objeto ou função.
Embora eu entenda o que você quis dizer, não acho correto dizer que o this seja um recurso para direcionar, o this é um recurso que permite variáveis dinâmicas, não estou falando do valor da variável, mas da própria variável em si. Não se pode dizer que um objecto tenha contexto, isto está errado. Cuidado com o uso da palavra contexto, pois existe o contexto quando nos referimos ao escopo e existe o contexto de execução que é outra coisa.


Durante o meu texto a palavra contexto será usada junto com a palavra execução, pois só irei usar ela para me referir ao contexto de execução, e usar escopo diretamente, tentando evitar a confusão.


Eu posso ter uma variável "nome" no escopo global, dentro de um objeto ou dentro de uma função e quem vai ajudar a função a determinar qual das variáveis "nome" vai chamar é o this, estou correto?
Eu acho que entendi o que você quis dizer, mas no seu código, o que está sendo identificado como "nome" é uma propriedade e não uma variável.... Ou pelo menos é o que se pretende que seja no caso do "this.nome", pois como já falei, o this só vai ser "definido" por ocasião da execução do código. Caso o valor do this seja um objecto aí sim estará correto a tentativa de se acessar a propriedade "nome".

Aqui teríamos muito o que abordar, mas resumindamente, posso dizer que: (estando esse código sendo executado pelo global) caso a execução esteja sendo realizada em strict-mode o valor do this por ocasião da execução será undefined, e um erro (Reference Error) será lançado, pois a propriedade "nome" não pode existir em undefined. Caso estejas executando em non-strict-mode o this (no global, nos browsers) vai receber por ocasião da execução o valor do objecto "window" e portanto ao se tentar ler a propriedade "nome", caso ela não exista, será criada no objecto "window" e terá o valor undefined.

Logo não é que "nome" vá estar no escopo global, em non-strict-mode, o que temos é que, na execução do código, se irá tentar acessar a propriedade "nome" do objecto "window" (nos browsers).

Mesmo dentro da função o que se está a fazer é acessar a propriedade "nome" de um possível objecto que o this venha a referenciar. Por acaso, nessa execução em concreto, o this, dentro da função, caso não lhe seja atribuído um outro valor explicitamente, será o mesmo do this que tens do lado de fora, ou seja, no caso non-strict-mode, será o objecto "window" (nos browsers).

this.nome = 'Wivson' //Aqui estou usando o this para determinar a variável "nome" que será inserido no escopo global
- nome é propriedade e em qual objecto se irá tentar acessar essa propriedade, depende da execução do código, no caso de non-stric-mode e dos browsers, o this terá implicitamente o valor do objecto "window".

let pessoa = { nome: 'Mário' //Aqui defini a variável "nome" dentro do objeto pessoa(escopo local) }
- (propriedade nome). Objectos NÃO TEM ESCOPO (isto coloquei em caixa alta, porque é muito importante para que você possa compreender melhor o funcionamento do javascript). Não se pode falar de escopo local de objectos!

function pegarNome(){ console.log(this.nome) //Função para pegar o resultado de uma variável "nome" independente do escopo que ela estiver }
- excelente exemplo para mostrar poder do this. O poder de ser dinâmico. A função exibe o valor da propriedade nome de um objecto (assim esperemos que seja) que ainda não sabemos quem é... Não sabemos o que o this será. É dinâmico. A única coisa que podemos afirmar é que muito provavelmente será um objecto, pois só objectos possuem propriedades.


const imprimirNomeGlobal = pegarNome.bind(this) //O bind pede a referencia de onde o this da função vai pegar a variável "nome", nesse caso o this se refere ao escopo global
- O bind na verdade retorna uma nova função a Biding Function (o nome pode não ser este exatamente, my bad). Esta Binding Function é especial, pois no seu contexto de execução o valor do this fica amarrado ao que lhe for atribuído na ocasião da sua definição, isto é, no momento do "fn.bind(...)". A execução do método bind do Function prototype é o retorno da definição de uma função. No seu caso esa definição ficou associada à variável "imprimirNomeGlobal" que por sua vez quando for executado, no seu contexto de execução, o valor do this será aquele que lhe foi definido, no seu caso o mesmo valor do this no momento em que o "pegarNome.bind(this)" foi executado, neste caso o tal objecto "window".
O this NÃO SE REFERE a escopos, não se pode dizer que o this se refere ao escopo global, não faz sentido.

const imprimirNomeLocal = pegarNome.bind(pessoa) //O bind pede a referencia de onde o this da função vai pegar a variável "nome", nesse caso a referencia é o objeto "pessoa", a função "pegarNome" vai dentro do objeto pessoa e procura uma variável "nome"
- O mesmo de cima, a diferença é que no momento da execução desta função "pegarNome.bind(pessoa)" o valor que foi "amarrado" ao this do "futuro" contexto de execução da "imprimirNomeLocal" é o objecto "pessoa".


O recurso this permite que sejam criadas funções genéricas que podem acessar variáveis de nomes iguais em escopos diferentes apenas direcionando o escopo, fazendo o reaproveitamento da função bem melhor e tornando o código mais simples, uma vez que posso acessar variáveis de mesmo nome mesmo estando em escopos diferentes.
- parcialmente correto, mas acho que com o que falei acima já seria possível alterar esta conclusão. Caso tenha baralhado mais ainda, não se chateie comigo, a verdade é que estas coisas levam tempo. O fato de você ter escrito tudo o que escreveu já é indicação que falta pouquinho para você compreender realmente o que é o this (no javascript).

Acho que você está no caminho, e não perderia muito tempo entendendo a fundo o que o this é ou faz, vai por camadas, um pouquinho de cada vez sobre cada parte do universo javascript. O que quero dizer é: procure agora entender escopo no javascript: o que é isso de ser léxico. Em que fase a montagem do escopo ocorre? Como acontece este mecanismo?...

E novamente, eu não me preocuparia em entender tudão, mas apenas parte do problema e assim aos poucos vai ligando uma coisa com a outra com mais cuidado e entendendo melhor o que as coisas são e fazem.

Eu me coloco à disposição caso queiras debater algum assunto em JS seja este ou qualquer outro.

Caso eu tenha te confundido mais ainda, me desculpe e me aponte onde para que eu possa melhorar a mensagem.

Um grande abraço.
 

Wivson Machado

Novo Membro
Cadastro
28/12/20
Postagens
8
Curtidas
10
Pontuação
19
Cidade
Niterói
Fala @mourabraz blz, meu amigo?!
Tudo na paz!

Cara, eu consegui entender algumas coisas que você explicou e outras confesso que embaralhou mais ainda, mas eu sei que isso é normal... quando me referi à variável, realmente o que eu estava querendo era propriedade mas me faltou o vocabulário na hora... risos

Certeza que vou precisar reler a sua explicação várias e várias vezes e assimilar aos poucos, mas pelo que puder entender o poder do this é muito maior do que apenas acessar dinamicamente a propriedade de um objeto como eu havia pensando.

Muito obrigado mesmo pela resposta, por clarear algumas coisa e nublar outras, porque isso vai me fazer ir mais em busca ainda.

Grande Abraço.
 

mourabraz

Membro
Moderador
Cadastro
23/12/20
Postagens
101
Curtidas
151
Pontuação
100
Cidade
Leiria
Oi que legal camarada @Wivson Machado, mas lembre-se que se precisar posso lhe ajudar. (ou pelo menos tentar, tenho muita dificuldade em expor as coisas ainda...)

Se quiser ao fim de semana é possível trocar uma ideia por video chamada e assim interagir melhor e tentar clarear os pontos. Legal que se eu conseguir cumprir isso você depois poderia expor aqui o seu entendimento e assim ajudar outros.

Qualquer coisa só falar.

Abraços.

PS. temos de levar em conta o fuso horário, em relação a brasília aqui são 4 horas mais tarde.
 
Top