es6 - mozilla prototype javascript
Convención para la herencia del prototipo en JavaScript (3)
''constructor'' no hace lo que parece que hace. Esto, además de su falta de uniformidad, es una buena razón para evitar usarlo: seguir con instanceof y prototipo.
Técnicamente: ''constructor'' no es una propiedad de la instancia ''s'', es una propiedad del objeto prototipo ''Sub'' que se ve a través de. Cuando creas la función ''Sub'' en Mozilla, obtienes un objeto Sub.prototype por defecto recién creado que tiene un ''constructor'' apuntando hacia atrás a la función Sub como cortesía.
Sin embargo, luego reemplaza ese prototipo con una nueva Base (). El prototipo original por defecto con el enlace de regreso a Sub se pierde; en su lugar, Sub.prototype es una instancia de Base sin ninguna propiedad ancestral de ''constructor''. Asi que:
new Sub().constructor===
Sub.prototype.constructor===
new Base().constructor===
Base.prototype.constructor===
Base
... todo el camino hasta el objeto más básico cuyo prototipo no cambiaste.
¿Es convencional / mejor hacer esto?
Cuando se trata de objetos / clases de JavaScript, no hay una sola convención; el sistema de metaclase de cada biblioteca se comporta de forma ligeramente diferente. No he visto uno que escriba ''constructor'' para cada clase derivada manualmente, pero parece una solución tan buena como cualquiera si realmente quieres tener el constructor real disponible; también hará que el código sea compatible con navegadores / motores que no le dan ''constructor''.
Sin embargo, consideraría darle un nombre diferente para evitar confusiones con la propiedad de ''constructor'' existente y de comportamiento diferente.
Veo muchos códigos como este:
function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sin embargo, si lo haces:
s = new Sub();
print(s.constructor == Sub);
Esto es falso Esto me parece confuso, ya que el constructor de s es, de hecho, Sub. ¿Es convencional / mejor hacer esto?
function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sub.prototype.constructor = Sub;
o realmente no importa?
Si desea probar si un objeto es exactamente una instancia de Sub utilice el operador instanceof
: -
print(s instanceof Sub);
Si desea saber si un objeto es una instancia de Sub o una instancia de una subclase de Sub, utilice el método isPrototypeOf
: -
print(Sub.prototype.isPrototypeOf(s));
Sí,
Sub.prototype.constructor = Sub;
vamos a usar instanceof pero hay una mejor solución. Mire aquí:, TDD JS Herencia en GitHub , y encuentre el patrón de herencia de combinación parasitaria . El código está TDD''d así que deberías poder asimilarlo rápidamente y luego simplemente cambiar los nombres para que comiences. Esto es básicamente lo que usa YAHOO.lang.extend (fuente: empleado y autor de yahoo Nicholas Zakas''s Professional JavaScript for Web Developer''s, 2nd ED, page 181). Buen libro por cierto (¡no afiliado de ninguna manera!)
¿Por qué? Debido a que el patrón clásico con el que está trabajando tiene vars de referencia staticy (si crea var arr = [1,2] en el objeto base, TODAS las instancias tendrán lectura / escritura y "compartirán estado" de ''arr''! use robo de constructor para evitar esto. Vea mis ejemplos.