2017-09-24 90 views
1

使用ES6類製作一個簡單的ORM,我使用阻塞問題運行 - 我無法正確複製一個類(就像我在ES5中使用util.extend)。如何克隆ES6類對象構造函數?

具體而言,這裏是我的嘗試:

class BaseModel { 

    echo() { 
    console.log(this.props); 
    } 

    static _setProperties(props) { 
    this.props = props; 
    } 

} 

function makeModel(props) { 

    // Try to copy the Class object 
    const Model = 
     Object.assign(Object.create(Object.getPrototypeOf(BaseModel)), BaseModel); 

    // Copy my static methods – is there a better way to do this? 
    Object.getOwnPropertyNames(BaseModel).forEach((key) => { 
    if (!key.startsWith('_')) return; 
    Model[key] = BaseModel[key]; 
    }); 

    // Configure the new model 
    Model._setProperties(props); 
    return Model; 
} 

const GreeterModel = makeModel('hello'); 
const greeter = new GreeterModel(); 
greeter.echo(); // Should log hello 

我得到的錯誤是:

TypeError: GreeterModel is not a constructor 

有沒有辦法用ES6類來實現這一點,或者我要堅持ES5風格?

可選問題:有沒有更好的方法來複制靜態方法? getOwnPropertyNames的解決方案並不理想,因爲它還返回只讀屬性,如length

謝謝!

+0

'Object.create'不會創建函數,這段代碼也不能用於ES5。 – Bergi

+0

爲什麼不使用ES6'class extends'? – Bergi

回答

5

你的基類有一個邏輯錯誤。 this總是取決於如何調用一個函數。靜態函數通常在構造函數上調用,即BaseModel._setProperties(...),在這種情況下,this指的是BaseModel。 但實例方法在實例本身上調用,因此this引用的實例不是構造函數。

爲了使BaseModel工作,你將不得不使用

echo() { 
    console.lof(this.constructor.props); 
} 

但是,爲了回答您的實際問題,你可以簡單地擴展類:

function makeModel(props) { 
    class Model extends BaseModel {} 
    Model._setProperties(props); 
    return Model; 
} 

注意,這不是「克隆「基礎課,它正在擴展它。在JavaScript中克隆函數沒有合理的方法(至少不會那麼肥胖)。