A new
palavra-chave em JavaScript pode ser bastante confusa quando é encontrada pela primeira vez, pois as pessoas tendem a pensar que o JavaScript não é uma linguagem de programação orientada a objetos.
- O que é isso?
- Que problemas ele resolve?
- Quando é apropriado e quando não?
javascript
new-operator
Alon Gubkin
fonte
fonte
Respostas:
Faz 5 coisas:
this
variável aponte para o objeto recém-criado.this
é mencionado.null
referência não- objeto. Nesse caso, a referência ao objeto é retornada.Nota: a função construtora refere-se à função após a
new
palavra - chave, como emUma vez feito isso, se uma propriedade indefinida do novo objeto for solicitada, o script verificará o objeto [[protótipo]] do objeto para a propriedade. É assim que você pode obter algo semelhante à herança de classe tradicional em JavaScript.
A parte mais difícil sobre isso é o ponto número 2. Todo objeto (incluindo funções) tem essa propriedade interna chamada [[prototype]] . Ele só pode ser definido no momento da criação do objeto, seja com new , com Object.create ou com base no literal (funções padrão para Function.prototype, números para Number.prototype etc.). Só pode ser lido com Object.getPrototypeOf (someObject) . Não há outra maneira de definir ou ler esse valor.
As funções, além da propriedade [[prototype]] oculta , também possuem uma propriedade chamada prototype , e é isso que você pode acessar e modificar para fornecer propriedades e métodos herdados para os objetos que você cria.
Aqui está um exemplo:
É como herança de classe porque agora, todos os objetos que você criar usando
new ObjMaker()
também parecerão ter herdado a propriedade 'b'.Se você quiser algo como uma subclasse, faça o seguinte:
Li uma tonelada de lixo sobre esse assunto antes de finalmente encontrar esta página , onde isso é explicado muito bem com bons diagramas.
fonte
ObjMaker
é definido como uma função que retorna um valor?new
existe para que você não precise escrever métodos de fábrica para construir / copiar funções / objetos. Significa: "Copie isso, tornando-o exatamente como sua 'classe' pai; faça-o de maneira eficiente e correta; e armazene informações de herança acessíveis apenas a mim, JS, internamente". Para fazer isso, modifica o interno inacessívelprototype
do novo objeto para encapsular opacamente os membros herdados, imitando as cadeias de herança OO clássicas (que não são modificáveis em tempo de execução). Você pode simular isso semnew
, mas a herança poderá ser modificada em tempo de execução. Boa? Ruim? Você decide.Notice that this pattern is deprecated!
. Qual é o padrão atualizado correto para definir o protótipo de uma classe?Suponha que você tenha esta função:
Se você chamar isso como uma função autônoma como esta:
A execução desta função adicionará duas propriedades ao
window
objeto (A
eB
). Ele é adicionado aowindow
porquewindow
é o objeto que chamou a função quando você a executa dessa maneira, ethis
em uma função é o objeto que chamou a função. Em Javascript, pelo menos.Agora, chame assim com
new
:O que acontece quando você adiciona
new
uma chamada de função é que um novo objeto é criado (apenasvar bar = new Object()
) e quethis
dentro da função aponta para o novo queObject
você acabou de criar, em vez do objeto que chamou a função. Entãobar
agora é um objeto com as propriedadesA
eB
. Qualquer função pode ser um construtor, mas nem sempre faz sentido.fonte
window
implicitamente um método . Mesmo em um fechamento, mesmo que anônimo. No entanto, no exemplo, é uma chamada de método simples na janela:Foo();
=>[default context].Foo();
=>window.Foo();
. Nesta expressãowindow
está o contexto (não apenas o chamador , o que não importa).Além da resposta de Daniel Howard, aqui está o que
new
faz (ou pelo menos parece fazer):Enquanto
é equivalente a
fonte
func.prototype
sernull
? Poderia, por favor, elaborar um pouco sobre isso?A.prototype = null;
Nesse casonew A()
resultará em no objeto, isso é pontos protótipos internos para oObject
objeto: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
teste facilita a compreensão do que está acontecendo nos bastidores.Para iniciantes entender melhor
experimente o seguinte código no console do navegador.
Agora você pode ler a resposta do wiki da comunidade :)
fonte
return this;
produz a mesma saída.É usado exatamente para isso. Você define um construtor de função da seguinte maneira:
No entanto, o benefício extra que o ECMAScript possui é que você pode estender a
.prototype
propriedade, para que possamos fazer algo como ...Todos os objetos criados a partir deste construtor agora terão uma
getName
causa da cadeia de protótipos à qual eles têm acesso.fonte
class
palavra-chave, mas é possível fazer a mesma coisa.JavaScript é uma linguagem de programação orientada a objetos e é usada exatamente para criar instâncias. É baseado em protótipo, em vez de baseado em classe, mas isso não significa que não seja orientado a objetos.
fonte
Javascript é uma linguagem de programação dinâmica que suporta o paradigma de programação orientada a objetos e é usada para criar novas instâncias de objeto.
Classes não são necessárias para objetos - Javascript é uma linguagem baseada em protótipo .
fonte
Já existem respostas muito boas, mas estou postando uma nova para enfatizar minha observação no caso III abaixo sobre o que acontece quando você tem uma declaração de retorno explícita em uma função que está
new
desenvolvendo. Veja os casos abaixo:Caso I :
Acima está um caso simples de chamar a função anônima apontada por
Foo
. Quando você chama essa função, ela retornaundefined
. Como não há uma declaração de retorno explícita, o intérprete de JavaScript insere forçosamente umareturn undefined;
declaração no final da função. Aqui janela é o objeto invocação (contextualthis
) que recebe novoA
eB
propriedades.Caso II :
Aqui, o intérprete JavaScript, vendo a
new
palavra - chave, cria um novo objeto que atua como o objeto de invocação (contextualthis
) da função anônima apontada porFoo
. Nesse caso, torneA
-B
se propriedades no objeto recém-criado (no lugar do objeto de janela). Como você não possui nenhuma declaração de retorno explícita, o intérprete JavaScript insere forçosamente uma declaração de retorno para retornar o novo objeto criado devido ao uso danew
palavra-chave.Caso III :
Aqui, novamente, o intérprete JavaScript, vendo a
new
palavra - chave, cria um novo objeto que atua como o objeto de invocação (contextualthis
) da função anônima apontada porFoo
. NovamenteA
eB
torne - se propriedades no objeto recém-criado. Mas desta vez você tem uma declaração de retorno explícita para que o intérprete JavaScript não faça nada por conta própria.O ponto a ser observado no caso III é que o objeto que está sendo criado devido à
new
palavra - chave se perdeu do seu radar.bar
está na verdade apontando para um objeto completamente diferente, que não é aquele criado pelo interpretador JavaScript devido ànew
palavra - chave.Citando David Flanagan de JavaScripit: The Definitive Guide (6th Edition), cap. 4, página 62:
--- Informações adicionais ---
As funções usadas no snippet de código dos casos acima têm nomes especiais no mundo JS, como abaixo:
Caso I e II - Função Construtora
Caso III - Função de fábrica. As funções de fábrica não devem ser usadas com a
new
palavra - chave que fiz para explicar o conceito no encadeamento atual.Você pode ler sobre a diferença entre eles neste tópico.
fonte
Às vezes, o código é mais fácil que as palavras:
para mim, contanto que eu não protótipo, uso o estilo de func2, pois ele me proporciona um pouco mais de flexibilidade dentro e fora da função.
fonte
B1 = new func2(2);
<- Por que isso não vai terB1.y
?A
new
palavra-chave altera o contexto no qual a função está sendo executada e retorna um ponteiro para esse contexto.Quando você não usa a
new
palavra - chave, o contexto no qual a funçãoVehicle()
é executada é o mesmo contexto no qual você está chamando aVehicle
função. Athis
palavra-chave se referirá ao mesmo contexto. Quando você usanew Vehicle()
, um novo contexto é criado para que a palavra-chavethis
dentro da função se refira ao novo contexto. O que você recebe em troca é o contexto recém-criado.fonte
A
new
palavra-chave é para criar novas instâncias de objetos. E sim, o javascript é uma linguagem de programação dinâmica, que suporta o paradigma de programação orientada a objetos. A convenção sobre a nomeação de objetos é sempre usar letras maiúsculas para objetos que devem ser instanciados pela nova palavra-chave.fonte
Resumo:
A
new
palavra-chave é usada em javascript para criar um objeto a partir de uma função de construtor. Anew
palavra-chave deve ser colocada antes da chamada da função do construtor e fará o seguinte:this
palavra-chave ao objeto recém-criado e executa a função construtoraExemplo:
O que exatamente acontece:
const doggie
diz: Precisamos de memória para declarar uma variável.=
diz: Vamos inicializar essa variável com a expressão após o=
new Dog(12)
. O mecanismo JS vê a nova palavra-chave, cria um novo objeto e define o protótipo como Dog.prototypethis
valor definido para o novo objeto. Nesta etapa, é onde a idade é atribuída ao novo objeto cachorrinho criado.fonte
A
new
palavra-chave cria instâncias de objetos usando funções como construtor. Por exemplo:Instâncias herdam da
prototype
função construtora. Então, dado o exemplo acima ...fonte
Bem, o JavaScript por si pode diferir bastante de plataforma para plataforma, pois é sempre uma implementação da especificação original EcmaScript.
De qualquer forma, independentemente da implementação, todas as implementações JavaScript que seguem a especificação EcmaScript corretamente fornecem uma Linguagem Orientada a Objetos. De acordo com o padrão ES:
Então agora que concordamos que o JavaScript é uma implementação do EcmaScript e, portanto, é uma linguagem orientada a objetos. A definição da
new
operação em qualquer linguagem orientada a objetos diz que essa palavra-chave é usada para criar uma instância de objeto a partir de uma classe de um determinado tipo (incluindo tipos anônimos, em casos como C #).No EcmaScript, não usamos classes, como você pode ler nas especificações:
fonte