¿Se considera perjudicial la palabra clave "nueva" de JavaScript? [cerrado]

568

En otra pregunta , un usuario señaló que la newpalabra clave era peligrosa de usar y propuso una solución para la creación de objetos que no se usó new. No creía que eso fuera cierto, principalmente porque he usado Prototype, Scriptaculous y otras excelentes bibliotecas de JavaScript, y todos ellos usaron la newpalabra clave.

A pesar de eso, ayer estaba viendo la charla de Douglas Crockford en el teatro YUI y dijo exactamente lo mismo, que ya no usaba la newpalabra clave en su código ( Crockford en JavaScript - Acto III: Function the Ultimate - 50:23 minutos ).

¿Es 'malo' usar la newpalabra clave? ¿Cuáles son las ventajas y desventajas de usarlo?

Pablo Fernández
fuente
90
NO es 'malo' usar la nueva palabra clave. Pero si lo olvida, llamará al constructor de objetos como una función regular. Si su constructor no comprueba su contexto de ejecución, entonces no notará que 'esto' apunta a un objeto diferente (normalmente el objeto global) en lugar de la nueva instancia. Por lo tanto, su constructor agregará propiedades y métodos al objeto global (ventana). Si siempre verifica que 'esto' es una instancia de su objeto en la función de objeto, entonces nunca tendrá este problema.
Kristian B
55
No entiendo esto Por un lado, Douglas desalienta el uso de new. Pero cuando miras la biblioteca YUI. Tienes que usar en newtodas partes. Tales como var myDataSource = new Y.DataSource.IO({source:"./myScript.php"}); .
aditya_gaur
2
@aditya_gaur Eso se debe a que si necesita un poco de inicialización de un objeto, tendría que hackear un initmétodo si está utilizando el Object.createenfoque y llamarlo después. Mucho más fácil de usar newque hace ambas cosas, establece la cadena del prototipo y llama a un código inicializador.
Juan Mendes
67
No creo que esto deba haberse cerrado. Sí, es probable que inspire un poco de veneno anti-fanático de Crockford, pero estamos hablando de consejos populares para evitar básicamente una característica principal del idioma aquí. El mecanismo que hace que cada objeto JQuery no pese casi nada (en lo que respecta a la memoria) implica el uso de la palabra clave 'nuevo'. Prefiera los métodos de fábrica para invocar constantemente nuevas, pero no reduzca drásticamente sus opciones arquitectónicas y su potencial de rendimiento utilizando solo literales de objetos. Tienen su lugar y los constructores tienen su lugar. Es un consejo anticuado y pésimo.
Erik Reppen
2
TLDR: Usar newno es peligroso. Omitir newes peligroso y, por lo tanto, malo . Pero en ES5 puede usar el modo estricto , que lo protege de ese peligro y de muchos otros.
jkdev

Respuestas:

603

Crockford ha hecho mucho para popularizar buenas técnicas de JavaScript. Su postura obstinada sobre los elementos clave del lenguaje ha provocado muchas discusiones útiles. Dicho esto, hay demasiadas personas que toman cada proclamación de "malo" o "dañino" como un evangelio, y se niegan a mirar más allá de la opinión de un hombre. Puede ser un poco frustrante a veces.

El uso de la funcionalidad proporcionada por la newpalabra clave tiene varias ventajas sobre la construcción de cada objeto desde cero:

  1. Prototipo de herencia . Aunque a menudo se observa con una mezcla de sospecha y burla por parte de aquellos acostumbrados a los lenguajes de OO basados ​​en clases, la técnica de herencia nativa de JavaScript es un medio simple y sorprendentemente efectivo de reutilización de código. Y la nueva palabra clave es el medio canónico (y solo disponible multiplataforma) para usarlo.
  2. Actuación. Este es un efecto secundario del n. ° 1: si quiero agregar 10 métodos a cada objeto que creo, podría escribir una función de creación que asigne manualmente cada método a cada nuevo objeto ... O podría asignarlos al funciones de creación prototypey uso newpara estampar nuevos objetos. Esto no solo es más rápido (no se necesita código para todos y cada uno de los métodos del prototipo), sino que también evita que cada objeto tenga globos con propiedades separadas para cada método. En máquinas más lentas (o especialmente, intérpretes JS más lentos) cuando se crean muchos objetos, esto puede significar un ahorro significativo de tiempo y memoria.

Y sí, newtiene una desventaja crucial, descrita hábilmente por otras respuestas: si olvida usarlo, su código se romperá sin previo aviso. Afortunadamente, esa desventaja se mitiga fácilmente: simplemente agregue un poco de código a la función en sí:

function foo()
{
   // if user accidentally omits the new keyword, this will 
   // silently correct the problem...
   if ( !(this instanceof foo) )
      return new foo();

   // constructor logic follows...
}

Ahora puede tener las ventajas de newsin tener que preocuparse por los problemas causados ​​por un mal uso accidental. Incluso podría agregar una afirmación al cheque si la idea de que el código roto funcione silenciosamente le molesta. O, como algunos comentaron, use la verificación para introducir una excepción de tiempo de ejecución:

if ( !(this instanceof arguments.callee) ) 
   throw new Error("Constructor called as a function");

(Tenga en cuenta que este fragmento puede evitar codificar el nombre de la función del constructor, ya que, a diferencia del ejemplo anterior, no tiene necesidad de crear una instancia del objeto; por lo tanto, se puede copiar en cada función de destino sin modificación).

John Resig entra en detalles sobre esta técnica en su publicación de instanciación de "Clase" Simple , así como también incluye un medio para construir este comportamiento en sus "clases" de forma predeterminada. Definitivamente vale la pena leer ... al igual que su próximo libro, Secretos del JavaScript Ninja , que encuentra el oro oculto en esto y muchos otros "perjudicial" características del lenguaje JavaScript (el capítulo en withque se alumbra en especial para aquellos de nosotros que inicialmente rechazó esta característica muy difamada como un truco).

Shog9
fuente
96
if (! (this instanceof argumentos.callee)) throw Error ("Constructor llamado como una función"); // Más genérico, no requiere conocimiento del nombre del constructor, haga que el usuario arregle el código.
algunos
55
Si le preocupa el rendimiento, y en realidad tiene motivos para hacerlo, no haga la comprobación en absoluto. Recuerde usar new, o use una función de contenedor para recordarlo por usted. Yo sospecho que si usted está en el punto donde realmente importa, que haya agotado ya otras optimizaciones tales como memoization, por lo que sus llamadas de creación serán localizados todos modos ...
Shog9
65
Usar arguments.calleepara verificar si te han llamado newpuede no ser tan bueno, ya arguments.calleeque no está disponible en modo estricto. Es mejor usar el nombre de la función.
Sean McMillan
69
Si escribo mal un identificador, mi código se rompe. ¿No debería usar identificadores? No usarlo newporque puedes olvidarte de escribirlo en tu código es tan ridículo como mi ejemplo.
Thomas Eding
16
Si activa el modo estricto, si olvida usar nuevo, obtendrá una excepción cuando intente usar esto: yuiblog.com/blog/2010/12/14/strict-mode-is-coming-to-town Eso es más fácil que agregar una instancia de verificación a cada constructor.
stephenbez
182

Acabo de leer algunas partes de su libro de Crockfords "Javascript: The Good Parts". Tengo la sensación de que él considera que todo lo que lo ha mordido es dañino:

Sobre la caída del interruptor:

Nunca permito que los casos de cambio pasen al siguiente caso. Una vez encontré un error en mi código causado por una caída involuntaria inmediatamente después de haber pronunciado un discurso vigoroso sobre por qué la caída a veces era útil. (página 97, ISBN 978-0-596-51774-8)

Acerca de ++ y -

Se sabe que los operadores ++ (incremento) y - (decremento) contribuyen al mal código al alentar trucos excesivos. Solo son superados por una arquitectura defectuosa al habilitar virus y otras amenazas de seguridad. (página 122)

Acerca de nuevo:

Si olvida incluir el nuevo prefijo al llamar a una función constructora, entonces esto no estará vinculado al nuevo objeto. Lamentablemente, esto estará vinculado al objeto global, por lo que en lugar de aumentar su nuevo objeto, estará golpeando variables globales. Eso es realmente malo No hay advertencia de compilación y no hay advertencia de tiempo de ejecución. (página 49)

Hay más, pero espero que te hagas una idea.

Mi respuesta a su pregunta: No, no es dañino. pero si olvida usarlo cuando debería, podría tener algunos problemas. Si se está desarrollando en un buen entorno, lo nota.

Actualizar

Aproximadamente un año después de que se escribió esta respuesta, se lanzó la quinta edición de ECMAScript, con soporte para el modo estricto . En modo estricto, thisya no está vinculado al objeto global sino a undefined.

algunos
fuente
3
Estoy completamente de acuerdo. La solución: siempre documente cómo los usuarios tienen que instanciar sus objetos. Use un ejemplo y los usuarios probablemente cortarán / pegarán. Hay construcciones / características en cada idioma que pueden ser mal utilizadas, lo que resulta en un comportamiento inusual / inesperado. No los hace dañinos.
nicerobot
45
Existe una convención para iniciar siempre los constructores con una letra mayúscula y todas las demás funciones con una letra minúscula.
algunos
61
Me acabo de dar cuenta de que Crockford no considera MIENTRAS dañino ... No sé cuántas veces he creado un bucle infinitivo porque olvidé incrementar una variable ...
algunos
55
Lo mismo aplica para ++, -. Expresan exactamente lo que pretendo en el lenguaje más claro posible. Los amo! El cambio puede ser claro para algunos, pero estoy cansado de eso. Los uso cuando son claramente más claros (porque el juego de palabras, no pude resistir).
PEZ
30
Mi respuesta a Crockford: la programación es difícil, vamos de compras. Sheesh!
Jason Jackson
91

Javascript es un lenguaje dinámico, hay muchísimas formas de desordenar donde otro idioma te detendría.

Evitar una característica fundamental del lenguaje, como newla posibilidad de que se estropee, es como quitarse los zapatos nuevos y brillantes antes de caminar por un campo minado en caso de que se ensucie los zapatos.

Utilizo una convención donde los nombres de funciones comienzan con una letra minúscula y las 'funciones' que en realidad son definiciones de clase comienzan con una letra mayúscula. El resultado es una pista visual realmente convincente de que la 'sintaxis' está mal:

var o = MyClass();  // this is clearly wrong.

Además de esto, los buenos hábitos de nombres ayudan. Después de que todas las funciones hacen cosas y, por lo tanto, debe haber un verbo en su nombre, mientras que las clases representan objetos y son sustantivos y adjetivos sin verbo.

var o = chair() // Executing chair is daft.
var o = createChair() // makes sense.

Es interesante cómo la coloración de sintaxis de SO ha interpretado el código anterior.

AnthonyWJones
fuente
8
Sí, estaba pensando lo mismo sobre el color de la sintaxis.
BobbyShaftoe
44
Una vez que olvidé escribir la palabra 'función'. La palabra debe evitarse a toda costa. Otra vez no utilicé llaves en una declaración if / then de varias líneas. Así que ahora no uso llaves y solo escribo condicionales de una línea.
Hal50000
"Esto está claramente mal" . ¿Por qué? Para mis clases (que simplemente lo hacen if (! this instanceof MyClass) return new MyClass()) en realidad prefiero la newsintaxis -less. ¿Por qué? Porque las funciones son más genéricas que las funciones de constructor . Dejar de lado newhace que sea fácil cambiar una función de constructor a una función regular ... O al revés. Agregarlo newhace que el código sea más específico de lo que debe ser. Y por lo tanto menos flexible. Compare con Java donde se recomienda aceptar en Listlugar de ArrayListpara que la persona que llama pueda elegir la implementación.
Stijn de Witt
41

Soy un novato en Javascript, así que quizás no tengo mucha experiencia en proporcionar un buen punto de vista para esto. Sin embargo, quiero compartir mi punto de vista sobre esta "nueva" cosa.

Vengo del mundo de C #, donde usar la palabra clave "nuevo" es tan natural que es el patrón de diseño de fábrica lo que me parece extraño.

Cuando codifico por primera vez en Javascript, no me doy cuenta de que existe la palabra clave y el código "nuevos" como el del patrón YUI y no me lleva mucho tiempo encontrar el desastre. Pierdo la noción de lo que se supone que debe hacer una línea en particular cuando miro hacia atrás el código que he escrito. Más caótico es que mi mente realmente no puede transitar entre los límites de instancias de objetos cuando estoy "ejecutando en seco" el código.

Entonces, encontré la palabra clave "nueva" que para mí, "separó" las cosas. Con la nueva palabra clave, crea cosas. Sin la nueva palabra clave, sé que no la confundiré con la creación de cosas a menos que la función que estoy invocando me dé pistas sólidas sobre eso.

Por ejemplo, con var bar=foo();No tengo pistas sobre qué barra podría ser ... ¿Es un valor de retorno o es un objeto recién creado? Pero con lo que var bar = new foo();estoy seguro, la barra es un objeto.

Conrad
fuente
3
De acuerdo, y creo que el patrón de la fábrica debe seguir una convención de nomenclatura como makeFoo ()
pluckyglen
3
+1 - la presencia de 'nuevo' da una declaración de intención más clara.
belugabob
44
Esta respuesta es un poco extraña, cuando casi todo en JS es un objeto. ¿Por qué necesita saber con certeza que una función es un objeto cuando todas las funciones son objetos?
Joshua Ramirez
@JoshuaRamirez El punto no es eso typeof new foo() == "object". Es lo que newdevuelve una instancia de foo, y sabes que puedes llamar foo.bar()y foo.bang(). Sin embargo, eso se puede mitigar fácilmente utilizando @return de JsDoc No es que esté abogando por el código de procedimiento (evitando la palabra new)
Juan Mendes
1
@JuanMendes Hmm ... Su publicación me hizo pensar que le gustaban las novedades debido a su palabra clave explícita en su base de código. Puedo cavar eso. Por eso uso un patrón de módulo. Tendré una función llamada createFoo o NewFoo o MakeFoo, no importa mientras sea explícita. Dentro de eso, declaro variables que se usan como cierres dentro de un objeto literal que se devuelve desde la función. Ese objeto literal termina siendo su objeto, y la función era solo una función de construcción.
Joshua Ramirez
39

Otro caso para lo nuevo es lo que yo llamo Pooh Coding . Winnie the Pooh sigue su barriga. Yo digo ir con el lenguaje que estás usando, no en contra de él.

Lo más probable es que los mantenedores del lenguaje optimicen el lenguaje para los modismos que intentan alentar. Si ponen una nueva palabra clave en el idioma, probablemente piensen que tiene sentido ser claro al crear una nueva instancia.

El código escrito siguiendo las intenciones del lenguaje aumentará en eficiencia con cada versión. Y el código que evita las construcciones clave del lenguaje sufrirá con el tiempo.

EDITAR: Y esto va mucho más allá del rendimiento. No puedo contar las veces que escuché (o dije) "¿por qué demonios hicieron eso ?" al encontrar un código de aspecto extraño. A menudo resulta que en el momento en que se escribió el código había alguna razón "buena" para ello. Seguir el Tao del lenguaje es su mejor seguro para no tener su código ridiculizado en algunos años a partir de ahora.

PEZ
fuente
3
+1 para el enlace de codificación de Pooh: ahora necesito encontrar excusas para trabajar en mis conversaciones ...
Shog9
Jajaja Tengo años de experiencia en ese campo en particular y puedo asegurarle que no encontrará dificultades. A menudo me llaman Pooh en robowiki.net. =)
PEZ
1
No sé si alguna vez verás este comentario, pero ese enlace de Pooh Coding está muerto.
Calvin el
Gracias por el aviso. Migramos robowiki.net a un nuevo wiki la semana pasada y el contenido antiguo es inalcanzable en este momento. Me apresuraré a hacer que esos viejos enlaces funcionen.
PEZ
24

Escribí una publicación sobre cómo mitigar el problema de llamar a un constructor sin la nueva palabra clave.
Es principalmente didáctico, pero muestra cómo puede crear constructores que funcionen con o sin ellos newy no requiere que agregue código repetitivo para probar thisen cada constructor.

http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html

Aquí está la esencia de la técnica:

/**
 * Wraps the passed in constructor so it works with
 * or without the new keyword
 * @param {Function} realCtor The constructor function.
 *    Note that this is going to be wrapped
 *    and should not be used directly 
 */
function ctor(realCtor){
  // This is going to be the actual constructor
  return function wrapperCtor(){
    var obj; // object that will be created
    if (this instanceof wrapperCtor) {
      // Called with new
      obj = this;
    } else {
      // Called without new. Create an empty object of the
      // correct type without running that constructor
      surrogateCtor.prototype = wrapperCtor.prototype;
      obj = new surrogateCtor();
    }
    // Call the real constructor function
    realCtor.apply(obj, arguments);
    return obj;
  }

  function surrogateCtor() {}
}

Aquí se explica cómo usarlo:

// Create our point constructor
Point = ctor(function(x,y){
  this.x = x;
  this.y = y;
});

// This is good
var pt = new Point(20,30);
// This is OK also
var pt2 = Point(20,30);
Juan mendes
fuente
66
¡evitar arguments.calleees increíble!
Gregg Lind
2
surrogateConstructordebería ser surrogateCtor(o viceversa).
David Conrad
Mantuve una colección de utilidades similares inspiradas en Crockford, y descubrí que siempre me hacía correr para encontrar las implementaciones cuando inicio un nuevo proyecto. Y esto envuelve una parte tan fundamental de la programación: la creación de instancias de objetos. ¿Todo este trabajo, solo para habilitar un código de instancia aleatorio? Agradezco el ingenio de este envoltorio, sinceramente, pero parece engendrar una codificación descuidada.
Joe Coder
1
@joecoder Mencioné que esto era solo para fines didácticos, no me suscribo a este estilo de codificación paranoico. Sin embargo, si estaba escribiendo una biblioteca de clase, entonces sí, agregaría esta función de manera transparente para las personas que llaman
Juan Mendes
22

La razón detrás de no usar la nueva palabra clave es simple:

Al no usarlo en absoluto, evita la trampa que viene al omitirlo accidentalmente. El patrón de construcción que utiliza YUI es un ejemplo de cómo puede evitar la nueva palabra clave por completo "

var foo = function () {
    var pub= { };
    return pub;
}
var bar = foo();

Alternativamente, podría hacerlo así:

function foo() { }
var bar = new foo();

Pero al hacerlo, corre el riesgo de que alguien se olvide de usar la nueva palabra clave, y este operador sea todo fubar. AFAIK no hay ninguna ventaja en hacer esto (aparte de que estás acostumbrado).

Al final del día: se trata de estar a la defensiva. ¿Puedes usar la nueva declaración? Si. ¿Hace tu código más peligroso? Si.

Si alguna vez ha escrito C ++, es similar a establecer punteros en NULL después de eliminarlos.

Greg Dean
fuente
66
No. Con "new foo ()" algunas propiedades se establecen en el objeto devuelto, como el constructor.
Algunos de
34
Entonces, solo para aclarar esto: ¿no deberías usar "nuevo" porque podrías olvidarlo? ¿Usted está tomando el pelo derecho?
Bombe
16
@Bombe: en otros idiomas, olvidar "nuevo" provocaría un error. En Javascript, solo sigue en camiones. Puedes olvidar y nunca darte cuenta. Y simplemente mirar el código erróneo no será obvio en absoluto lo que va mal.
Kent Fredric
3
@ Greg: No veo cómo la primera técnica permite el uso de cadenas de prototipos: los literales de objetos son geniales, pero descartar el rendimiento y otras ventajas proporcionadas por los prototipos por miedo parece un poco tonto.
Shog9
55
@Bombe: ¿Deberías usar "nuevo" porque tú (y cualquier persona que use tu código) nunca cometerán un error? ¿Usted está tomando el pelo derecho?
Greg Dean
20

Creo que "nuevo" agrega claridad al código. Y la claridad lo vale todo. Es bueno saber que hay dificultades, pero evitarlas evitando la claridad no parece ser el camino para mí.

PEZ
fuente
16

Caso 1: newno es obligatorio y debe evitarse

var str = new String('asd');  // type: object
var str = String('asd');      // type: string

var num = new Number(12);     // type: object
var num = Number(12);         // type: number

Caso 2: newes obligatorio; de lo contrario, recibirá un error

new Date().getFullYear();     // correct, returns the current year, i.e. 2010
Date().getFullYear();         // invalid, returns an error
nyuszika7h
fuente
55
Cabe señalar que en el caso 1, llamar al constructor como una función solo tiene sentido si tiene intención de conversión de tipo (y no sabe si el objeto del casco tiene un método de conversión, como toString()). En todos los demás casos, use literales. No String('asd') , sino simplemente 'asd', y no Number(12) , sino simplemente 12.
PointedEars
1
@PointedEars Una excepción a esta regla sería Array: Array(5).fill(0) obviamente es más legible que [undefined, undefined, undefined, undefined, undefined].fill(0)y(var arr = []).length = 5; arr.fill(0);
yyny
@YoYoYonnY Mi declaración se realizó en el contexto del caso 1 de la respuesta, que se refiere al uso de newcon constructores para tipos de objetos correspondientes a tipos primitivos . El literal que sugiere no es equivalente a la Arrayllamada (intente0 in … ), y el resto es un error de sintaxis :) De lo contrario, es correcto, aunque también debe tenerse en cuenta que Array(5)puede ser ambiguo si considera implementaciones no conformes (y por lo tanto, un emulado Array.prototype.fill(…) ).
PointedEars
12

Aquí está el resumen más breve que podría hacer de los dos argumentos más fuertes a favor y en contra del uso del newoperador:

Argumento en contra new

  1. Las funciones diseñadas para instanciarse como objetos que usan el newoperador pueden tener efectos desastrosos si se invocan incorrectamente como funciones normales. El código de una función en tal caso se ejecutará en el ámbito donde se llama la función, en lugar de en el ámbito de un objeto local como se pretendía. Esto puede hacer que las variables y propiedades globales se sobrescriban con consecuencias desastrosas.
  2. Finalmente, escribir function Func(), y luego llamar Func.prototype y agregar cosas para que pueda llamar new Func()para construir su objeto parece feo para algunos programadores, que prefieren usar otro estilo de herencia de objetos por razones arquitectónicas y estilísticas.

Para obtener más información sobre este argumento, consulte el excelente y conciso libro de Douglas Crockford Javascript: The Good Parts. De hecho, échale un vistazo de todos modos.

Argumento a favor de new

  1. Usar el newoperador junto con la asignación de prototipos es rápido.
  2. Las cosas sobre la ejecución accidental del código de una función de constructor en el espacio de nombres global se pueden evitar fácilmente si siempre incluye un poco de código en sus funciones de constructor para verificar si se invocan correctamente y, en los casos en que no , manejando la llamada apropiadamente según lo deseado.

Vea la publicación de John Resig para una explicación simple de esta técnica, y para una explicación generalmente más profunda del modelo de herencia que defiende.

alegscogs
fuente
Una actualización sobre los argumentos en contra: # 1 puede mitigarse mediante el uso del 'use strict';modo (o el método en su enlace) # 2 Tiene azúcar sincrónico en ES6 , sin embargo, el comportamiento es el mismo que antes.
ninMonkey
9

Estoy de acuerdo con pez y algunos aquí.

Me parece obvio que "nuevo" es la creación de objetos autodescriptivos, donde el patrón YUI que describe Greg Dean está completamente oscurecido .

La posibilidad de que alguien pueda escribir var bar = foo;o var bar = baz();donde baz no es un método de creación de objetos parece mucho más peligroso.

annakata
fuente
8

Creo que lo nuevo es malo, no porque si se olvida de usarlo por error puede causar problemas, sino porque arruina la cadena de herencia, haciendo que el lenguaje sea más difícil de entender.

JavaScript está orientado a objetos basado en prototipos. Por lo tanto, cada objeto DEBE ser creado a partir de otro objeto así var newObj=Object.create(oldObj). Aquí oldObj se llama prototipo de newObj (por lo tanto, "basado en prototipos"). Esto implica que si una propiedad no se encuentra en newObj , se buscará en oldObj . newObj por defecto será un objeto vacío, pero debido a su cadena de prototipo parece tener todos los valores de oldObj .

Por otro lado, si lo hace var newObj=new oldObj(), el prototipo de newObj es oldObj.prototype , que es innecesariamente difícil de entender.

El truco es usar

Object.create=function(proto){
  var F = function(){};
  F.prototype = proto;
  var instance = new F();
  return instance;
};

Está dentro de esta función y solo aquí se debe usar new. Después de esto, simplemente use el método Object.create () . El método resuelve el problema del prototipo.

Mihir Gogate
fuente
77
Para ser honesto, no estoy loco por esta técnica: no agrega nada nuevo y, como lo ilustra su respuesta, incluso puede terminar siendo una muleta. En mi humilde opinión, comprender las cadenas de prototipos y la creación de instancias de objetos es crucial para comprender JavaScript ... Pero si te incomoda usarlos directamente, entonces usar una función auxiliar para cuidar algunos detalles está bien, siempre y cuando recuerdes lo que eres haciendo. FWIW: una variación (algo más útil) de esto es parte de la ECMAScript 5th ed. estándar, y ya está disponible en algunos navegadores, ¡ así que debes tener cuidado de no redefinirlo ciegamente!
Shog9
Por cierto: no estoy seguro de por qué hiciste este CW, pero si quieres volver a publicarlo con las correcciones de formato que hice, ten cuidado de evitar esa casilla de verificación ...
Shog9
2
¿Innecesariamente difícil de entender? var c = new Car()es lo mismo que hacervar c = Object.create(Car.prototype); Car.call(c)
Juan Mendes