2009-02-08 11 views
10

Hej wszystkim, próbuję sprawdzić, czy argument przekazany do mojej funkcji jest nazwą klasy, tak, że mogę ją porównać do innych klas przy użyciu instanceof.Testowanie, jeśli coś jest klasą w javascript

Na przykład:

function foo(class1, class2) { 
    // Test to see if the parameter is a class. 
    if(class1 is a class) 
    { 
    //do some kind of class comparison. 
    if(class2 is a class) 
    { 
     if(class1 instanceof class2) 
     { 
      //... 
     } 
    } 
    else 
    { 
     //... 
    } 
    } 
    else 
    //... 
} 

Czy to możliwe? Mam problem z wyszukiwaniem w Google.

+0

Czy używasz biblioteki, która implementuje dziedziczenie klasyczne w JavaScript? – Nosredna

+0

Nie, używam zwykłego starego javascript: d – kgrad

Odpowiedz

15

naprawdę nie ma czegoś takiego jak "klasa" w javascript - wszystko oprócz prymitywów jest przedmiotem. Nawet funkcje są obiektami.

instanceof działa jednak z funkcjami. Sprawdź to link.

function Car(make, model, year) 
{ 
    this.make = make; 
    this.model = model; 
    this.year = year; 
} 
var mycar = new Car("Honda", "Accord", 1998); 
var a = mycar instanceof Car; // returns true 
var b = mycar instanceof Object; // returns true 
+1

"wszystko jest przedmiotem" - Niezupełnie. Typy pierwotne (liczba, łańcuch, bool, null i undefined) nie są obiektami. –

+1

@AndreasGrech - nie dokładnie, nawet prymitywne typy mają właściwości i metody oraz łańcuch prototypów, etc ... więc są także pewnym obiektem – Luckylooke

4

JavaScript nie ma zajęć. Posiada funkcje, które, gdy są używane z new, mogą być używane do tworzenia wystąpień obiektów. Dlatego naprawdę chcesz sprawdzić, czy funkcja class2. Istnieje wiele sposobów na osiągnięcie tego; obecny (1,3) realizacja isfunction() w jQuery wygląda następująco:

isFunction: function(obj) { 
    return toString.call(obj) === "[object Function]"; 
}, 

... Ale zobacz tutaj skręcania różnych metod: Best method of testing for a function in JavaScript?

0

Teraz, gdy mamy rodzimych implementacje ES6, istnieją "prawdziwe klas". Są to w dużej mierze cukier syntaktyczny do prototypowego dziedziczenia, tak jak w przypadku funkcji konstruktora, ale istnieją subtelne różnice i nie są one całkowicie zamienne.

Do tej pory jedynym sposobem znalazłem jest uzyskanie .toString() funkcji konstruktora prototyp obiektu i sprawdzić, czy zaczyna się class lub jeśli obiekt ma konstruktora i .toString() z że rozpoczyna się class.

Zauważ, że jeśli kod jest kompilowany (tj najbardziej Babel lub maszynopis konfiguracje), to powróci function... zamiast class... przy starcie (od klasy są transpiled do funkcji konstruktora).

function isClass(obj) { 
    const isCtorClass = obj.constructor 
     && obj.constructor.toString().substring(0, 5) === 'class' 
    if(obj.prototype === undefined) { 
    return isCtorClass 
    } 
    const isPrototypeCtorClass = obj.prototype.constructor 
    && obj.prototype.constructor.toString 
    && obj.prototype.constructor.toString().substring(0, 5) === 'class' 
    return isCtorClass || isPrototypeCtorClass 
} 

Będzie to działać tylko w rodzimych środowiskach (Chrome, Firefox, EDGE, node.js, etc.), które wdrożyły class do kodu, który nie został transpiled do function.

Zastosowanie:

class A {} 
class B extends A {} 
isClass(A) // true 
isClass(new A()) // true 
isClass(B) // true 
isClass(new B()) // true 

function C() {} 
isClass(C) // false 
isClass(new C()) // false 
isClass({}) // false 
isClass(Date) // false 
isClass(new Date()) // false 

//These cases return 'true' but I'm not sure it's desired 
isClass(Object.create(A)) // true  
const x = {} 
Object.setPrototypeOf(x, A) 
isClass(x) // true 

Jeśli istnieje lepszy sposób, chciałbym wiedzieć, co to jest.

Powiązane problemy