2009-02-08 46 views
10

嘿所有,我想測試是否傳遞給我的函數的參數是一個類名,以便我可以將它與使用instanceof的其他類進行比較。測試是否有什麼是類中的JavaScript

例如:

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 
    //... 
} 

這可能嗎?我在回答問題時遇到問題。

+0

您是否正在使用在JavaScript中實現經典繼承的庫? – Nosredna 2009-02-08 23:40:30

+0

不,我只是使用普通的javascript:d – kgrad 2009-02-09 02:50:52

回答

15

實在是沒有這樣的東西一個JavaScript中的「類」 - 除了基本類型外,其他都是對象。即使功能是對象。

儘管DOES可以使用instanceof。看看這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 
4

JavaScript沒有類。它具有與new一起使用的功能,可用於生成對象實例。因此,你真的想測試class2是否是一個函數。有很多方法可以實現這一點;目前(1.3)實現isFunction()jQuery中的是這樣的:

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

...但是,在這裏看到的不同的方法概要: Best method of testing for a function in JavaScript?

0

現在,我們有ES6的本機實現,還有 「真正的類」。與構造函數一樣,這些主要是用於原型繼承的語法糖,但是存在細微的差異,並且兩者不完全可以互換。

到目前爲止,我發現的唯一方法是獲取對象的原型的構造函數的.toString()並檢查它是否與class開始,或者如果對象有一個構造函數和開始的.toString()class。請注意,如果您的代碼已編譯(即:大多數Babel或TypeScript設置),那麼這將在運行時返回function...而不是class...(因爲類被轉換爲構造函數)。

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 
} 

這將僅在本地環境中已經實施class對於尚未transpiled到function碼器(Chrome,火狐,邊緣,Node.js的,等等)的工作。

用法:

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 

如果有更好的辦法,我很想知道它是什麼。