2012-07-27 10 views
12

Jeśli mam klasę:coffeescript: Użycie instanceof vs Class.constructor.name

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

I chcę, aby sprawdzić, czy dany przedmiot jest z prawej klasy, jest to zawsze bezpieczne constructor.name:

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

czy lepiej użyć instanceof:

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

jeden argument mam dla instanceof jest przy użyciu extends:

class BigHaha extends Haha 

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

ale jak bezpieczne jest to, będąc operatorem JavaScript - czuję się jak byłbym sceptyczny.

Z drugiej strony, z constructor.name jest bardzo jasne, co się dzieje. Czy jest zagwarantowane, że constructor.name zostanie ustawione na wszystkich obiektach?

Dzięki za wszelkie informacje.

Odpowiedz

17

Przede wszystkim constructor jest również prosto JavaScript:

Zwraca referencję do funkcji obiektu, który stworzył prototyp instancji.

Więc kiedy mówisz o.constructor, jesteś naprawdę robi prostą JavaScript, nazwa constructor dla funkcji inicjalizacji obiektu coffeescript jest oddzielna sprawa.

Teraz masz wybór między używaniem własności JavaScript a operatorem constructor lub JavaScriptem instanceof. constructor tylko mówi, co „klasa” został użyty do utworzenia obiektu, instanceof z drugiej strony:

[...] sprawdza, czy obiekt ma w swoim łańcuchu prototypu właściwość konstruktora prototype.

Tak więc instanceof jest właściwym wyborem, jeśli chcesz zezwolić na podklasę.

+0

Wielkie dzięki! Aby to potwierdzić, właściwość 'name' na konstruktorze to tak: CoffeeScript? I jest niezawodny w przypadku zajęć, w których nie interesują mnie sub/superklasy? – phenomnomnominal

+0

@phenomnomnominal: ['name' pochodzi z' Function' JavaScript] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name) i jest niestandardowe, więc może, ale nie musi praca. Użyj 'instanceof' lub porównaj funkcję' constructor' bezpośrednio. Ale tak naprawdę, po prostu użyj 'instanceof'. –

+1

Przypominam sobie dyskusję w kwestiach coffeescript na temat własności 'constructor.name', która została zmanipulowana przez zamknięcie/uglifyjs. Inną dobrą rzeczą jest to, że 'instanceof' jest naprawdę bezpieczny tylko dla twoich własnych obiektów, a nie typów wbudowanych. Ale zgadzam się, że w tym przypadku lepszym rozwiązaniem jest "instanceof". * Edytuj: * [tutaj jest podobna dyskusja] (https://github.com/mishoo/UglifyJS/issues/290). –