La new
palabra clave en JavaScript puede ser bastante confusa cuando se encuentra por primera vez, ya que las personas tienden a pensar que JavaScript no es un lenguaje de programación orientado a objetos.
- ¿Qué es?
- ¿Qué problemas resuelve?
- ¿Cuándo es apropiado y cuándo no?
javascript
new-operator
Alon Gubkin
fuente
fuente
Respuestas:
Hace 5 cosas:
this
variable apunte al objeto recién creado.this
se menciona.null
referencia que no sea de objeto. En este caso, se devuelve esa referencia de objeto en su lugar.Nota: la función constructora se refiere a la función después de la
new
palabra clave, como enUna vez hecho esto, si se solicita una propiedad indefinida del nuevo objeto, el script verificará el objeto [[prototipo]] del objeto en su lugar. Así es como puede obtener algo similar a la herencia de clase tradicional en JavaScript.
La parte más difícil de esto es el punto número 2. Cada objeto (incluidas las funciones) tiene esta propiedad interna llamada [[prototipo]] . Puede solamente puede establecer en tiempo de creación de objeto, ya sea con nuevo , con Object.create , o basado en el literal (funciones predeterminada para Function.prototype, números a Number.prototype, etc.). Solo se puede leer con Object.getPrototypeOf (someObject) . No hay otra forma de establecer o leer este valor.
Las funciones, además de la propiedad oculta [[prototipo]] , también tienen una propiedad llamada prototipo , y es esto a lo que puede acceder y modificar para proporcionar propiedades y métodos heredados para los objetos que crea.
Aquí hay un ejemplo:
Es como la herencia de clases porque ahora, cualquier objeto que hagas usando
new ObjMaker()
también parecerá haber heredado la propiedad 'b'.Si quieres algo como una subclase, entonces haz esto:
Leí un montón de basura sobre este tema antes de finalmente encontrar esta página , donde esto se explica muy bien con buenos diagramas.
fuente
ObjMaker
se define como una función que devuelve un valor?new
existe para que no tenga que escribir métodos de fábrica para construir / copiar funciones / objetos. Significa: "Copie esto, haciéndolo como su 'clase' principal; hágalo de manera eficiente y correcta; y almacene información de herencia a la que solo yo pueda acceder, JS, internamente". Para hacerlo, modifica el internoprototype
de otro modo inaccesible del nuevo objeto para encapsular opacamente los miembros heredados, imitando las cadenas de herencia OO clásicas (que no son modificables en tiempo de ejecución). Puede simular esto sinnew
, pero la herencia será modificable en tiempo de ejecución. ¿Bueno? ¿Malo? Depende de usted.Notice that this pattern is deprecated!
. ¿Cuál es el patrón actualizado correcto para establecer el prototipo de una clase?Supongamos que tiene esta función:
Si llama a esto como una función independiente de esta manera:
La ejecución de esta función agregará dos propiedades al
window
objeto (A
yB
). Lo agrega alwindow
porquewindow
es el objeto que llamó a la función cuando lo ejecuta así, ythis
en una función está el objeto que llamó a la función. En Javascript al menos.Ahora, llámalo así con
new
:Lo que sucede cuando agrega
new
a una llamada de función es que se crea un nuevo objeto (solovar bar = new Object()
) y quethis
dentro de la función apunta al nuevoObject
que acaba de crear, en lugar de al objeto que llamó a la función. Entonces,bar
ahora es un objeto con las propiedadesA
yB
. Cualquier función puede ser un constructor, simplemente no siempre tiene sentido.fuente
window
implícito. Incluso en un cierre, incluso si es anónimo. Sin embargo, en el ejemplo es una invocación de método simple en la ventana:Foo();
=>[default context].Foo();
=>window.Foo();
. En esta expresiónwindow
está el contexto (no solo la persona que llama , lo que no importa).Además de la respuesta de Daniel Howard, esto es lo que
new
hace (o al menos parece hacer):Mientras
es equivalente a
fuente
func.prototype
sernull
? ¿Podría por favor explicar un poco sobre eso?A.prototype = null;
En ese caso senew A()
obtendrá un objeto, esos puntos prototipo internos alObject
objeto: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
prueba simplemente hace que sea más fácil entender lo que está sucediendo detrás de escena.Para que los principiantes lo entiendan mejor
pruebe el siguiente código en la consola del navegador.
Ahora puedes leer la respuesta wiki de la comunidad :)
fuente
return this;
produce la misma salida.Se usa exactamente para eso. Define un constructor de funciones así:
Sin embargo, el beneficio adicional que tiene ECMAScript es que puede ampliar con la
.prototype
propiedad, para que podamos hacer algo como ...Todos los objetos creados a partir de este constructor ahora tendrán un
getName
debido a la cadena de prototipo a la que tienen acceso.fuente
class
palabras clave pero puedes hacer lo mismo.JavaScript es un lenguaje de programación orientado a objetos y se usa exactamente para crear instancias. Está basado en prototipos, más que en clases, pero eso no significa que no esté orientado a objetos.
fuente
Javascript es un lenguaje de programación dinámico que admite el paradigma de programación orientado a objetos, y se utiliza para crear nuevas instancias de objetos.
Las clases no son necesarias para los objetos: Javascript es un lenguaje basado en prototipos .
fuente
Ya hay algunas respuestas muy buenas, pero estoy publicando una nueva para enfatizar mi observación en el caso III a continuación sobre lo que sucede cuando tiene una declaración de retorno explícita en una función que está
new
activando. Echa un vistazo a los siguientes casos:Caso I :
Arriba hay un caso simple de llamar a la función anónima señalada por
Foo
. Cuando llama a esta función, vuelveundefined
. Como no hay una declaración de retorno explícita, el intérprete de JavaScript inserta con fuerza unareturn undefined;
declaración al final de la función. Aquí ventana es el objeto de invocación (contextualthis
) que obtiene nuevaA
yB
propiedades.Caso II :
Aquí, el intérprete de JavaScript que ve la
new
palabra clave crea un nuevo objeto que actúa como el objeto de invocación (contextualthis
) de la función anónima señalada porFoo
. En este casoA
yB
propiedades convertido en el objeto recién creado (en lugar del objeto de la ventana). Como no tiene ninguna declaración de retorno explícita, el intérprete de JavaScript inserta a la fuerza una declaración de retorno para devolver el nuevo objeto creado debido al uso de lanew
palabra clave.Caso III :
Aquí nuevamente el intérprete de JavaScript al ver la
new
palabra clave crea un nuevo objeto que actúa como el objeto de invocación (contextualthis
) de la función anónima señalada porFoo
. Nuevamente,A
yB
conviértase en propiedades en el objeto recién creado. Pero esta vez tiene una declaración de retorno explícita, por lo que el intérprete de JavaScript no hará nada por sí mismo.Lo que hay que tener en cuenta en el caso III es que el objeto que se está creando debido a la
new
palabra clave se perdió de su radar.bar
en realidad apunta a un objeto completamente diferente que no es el que el intérprete de JavaScript creó debido a lanew
palabra clave.Citando a David Flanagan de JavaScripit: The Definitive Guide (6th Edition), cap. 4, página # 62:
--- Información adicional ---
Las funciones utilizadas en el fragmento de código de los casos anteriores tienen nombres especiales en el mundo JS de la siguiente manera:
Caso I y II - Función de constructor
Caso III - Función de fábrica. Las funciones de fábrica no deben usarse con la
new
palabra clave que he hecho para explicar el concepto en el hilo actual.Puedes leer sobre la diferencia entre ellos en este hilo.
fuente
a veces el código es más fácil que las palabras:
Para mí, siempre que no prototipo, uso el estilo de func2, ya que me da un poco más de flexibilidad dentro y fuera de la función.
fuente
B1 = new func2(2);
<- ¿Por qué esto no tendráB1.y
?La
new
palabra clave cambia el contexto en el que se ejecuta la función y devuelve un puntero a ese contexto.Cuando no usa la
new
palabra clave, el contexto en el que seVehicle()
ejecuta la función es el mismo contexto desde el que está llamando a laVehicle
función. Lathis
palabra clave se referirá al mismo contexto. Cuando lo usanew Vehicle()
, se crea un nuevo contexto para que la palabra clavethis
dentro de la función se refiera al nuevo contexto. Lo que obtienes a cambio es el contexto recién creado.fuente
La
new
palabra clave es para crear nuevas instancias de objeto. Y sí, JavaScript es un lenguaje de programación dinámico, que admite el paradigma de programación orientado a objetos. La convención sobre la denominación de objetos es, siempre use letras mayúsculas para los objetos que se supone que deben ser instanciados por la nueva palabra clave.fuente
Resumen:
La
new
palabra clave se usa en JavaScript para crear un objeto a partir de una función constructora. Lanew
palabra clave debe colocarse antes de la llamada a la función del constructor y hará lo siguiente:this
palabra clave al objeto recién creado y ejecuta la función constructoraEjemplo:
Qué sucede exactamente:
const doggie
dice: Necesitamos memoria para declarar una variable.=
dice: Vamos a inicializar esta variable con la expresión después de=
new Dog(12)
. El motor JS ve la nueva palabra clave, crea un nuevo objeto y establece el prototipo en Dog.prototypethis
valor establecido para el nuevo objeto. En este paso es donde se asigna la edad al nuevo objeto perrito creado.fuente
La
new
palabra clave crea instancias de objetos utilizando funciones como constructor. Por ejemplo:Las instancias heredan de la
prototype
función constructora. Entonces, dado el ejemplo anterior ...fuente
Bueno, JavaScript per si puede diferir mucho de una plataforma a otra, ya que siempre es una implementación de la especificación original EcmaScript.
En cualquier caso, independientemente de la implementación, todas las implementaciones de JavaScript que sigan la especificación EcmaScript correcta le proporcionarán un lenguaje orientado a objetos. De acuerdo con el estándar ES:
Entonces, ahora que hemos acordado que JavaScript es una implementación de EcmaScript y, por lo tanto, es un lenguaje orientado a objetos. La definición de la
new
operación en cualquier lenguaje orientado a objetos, dice que dicha palabra clave se utiliza para crear una instancia de objeto de una clase de cierto tipo (incluidos los tipos anónimos, en casos como C #).En EcmaScript no usamos clases, como puede leer en las especificaciones:
fuente