2012-07-27 24 views
12

Si tengo una clase:CoffeeScript: El uso de instanceof vs Class.constructor.name

class Haha 
    constructor: (@lolAmount = 1) -> 
    alert @lolAmount 

Y quiero comprobar si un objeto es de la clase derecha, ¿Siempre es seguro de usar constructor.name:

haha = new Haha() 
unless haha.constructor.name is 'Haha' 
    throw Error 'Wrong type' 

o es mejor utilizar instanceof:

haha = new Haha() 
unless haha instanceof Haha 
    throw Error 'Wrong type' 

Uno de mis argumentos para instanceof es cuando se utiliza extends:

class BigHaha extends Haha 

bigHaha = new BigHaha 
console.log bigHaha instanceof Haha #true 

pero qué tan seguro es que, al ser un operador de JavaScript - Siento que debería ser escéptico al respecto.

Por otro lado, con constructor.name está muy claro lo que está sucediendo. ¿Está garantizado que constructor.name se establecerá en todos los objetos?

Gracias por cualquier información.

Respuesta

17

En primer lugar, es también constructor JavaScript recta:

devuelve una referencia a la función del objeto que creó el prototipo de la instancia.

Así, cuando decimos o.constructor, en realidad está haciendo JavaScript recta, el nombre constructor para la función de objeto de inicialización CoffeeScript es un asunto aparte.

Así que ahora tiene la opción entre usar la propiedad constructor de JavaScript o el operador instanceof de JavaScript. El constructor sólo le dice qué "clase" se utilizó para crear el objeto, instanceof por el contrario:

[...] comprueba si un objeto tiene en su cadena de prototipo de la propiedad prototype de un constructor.

Así que instanceof es la opción correcta si desea permitir la creación de subclases.

+0

¡Muchas gracias! Sin embargo, para confirmar, la propiedad 'name' en el constructor es CoffeeScript, sí? ¿Y es confiable para las clases en las que no me importan las subclases/superclases? – phenomnomnominal

+0

@phenomnomnominal: El ['name' viene de la' Función' de JavaScript] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name) y no es estándar, por lo que puede o no trabajo. Use 'instanceof' o compare la función' constructor' directamente. Pero realmente, solo usa 'instanceof'. –

+1

Recuerdo una discusión en los problemas de coffeescript sobre la propiedad 'constructor.name' siendo mutilada por closure/uglifyjs. Otra cosa buena que debes saber es que 'instanceof' es realmente seguro de usar para tus propios objetos, y no para los tipos integrados. Pero estoy de acuerdo, para este uso, 'instanceof' es la mejor opción. * Editar: * [aquí hay una discusión similar] (https://github.com/mishoo/UglifyJS/issues/290). –