2015-11-27 56 views
0

獲取訪問類的靜態屬性下面是最小的應用程序,它證明了問題:使用BabelJS 6

'use strict'; 

var _ = require('underscore'); 

class Model 
{ 
    constructor(value) { 
     this._value = value; 
    } 

    get value() { 
     return this._value; 
    } 

    toJS() { 
     return this.value; 
    } 
} 

class ObjectModel extends Model 
{ 
    static properties = {}; 

    constructor(value) { 
     super(_.extend({}, new.target.properties, _.pick(value, _.keys(new.target.properties)))); 
    } 
} 

class PostModel extends ObjectModel 
{ 
    static properties = { 
     title: 'Hello' 
     /* content: '<p>Lorem ipsum dolor sit amet</p>' */ 
    }; 
} 

console.log(new PostModel({title: 'Nice day', aa: 11, bb: 22}).toJS()); 

應該產生{title: 'Nice day'}。相反,它甚至沒有編譯。我得到這個:

$ babel app.js 
SyntaxError: app.js: 'this' is not allowed before super() 

我明白爲什麼這樣做是爲了對象屬性。但我不明白爲什麼這也是爲類變量完成的。

在BabelJS 5我用這一招其做了工作:

class ObjectModel extends Model 
{ 
    static properties = {}; 

    constructor(value) { 
     if (0) { super(); } 
     super(_.extend({}, this.constructor.properties, _.pick(value, _.keys(this.constructor.properties)))); 
    } 
} 

在第6版它編譯,但在運行時會產生錯誤:

Uncaught TypeError: Cannot read property 'constructor' of undefined 

是否有某種方式來獲得在調用super之前訪問一個類的靜態變量?使用類似init()而不是constructor不是一種選擇。也許創建自定義轉換插件?

系統的細節:

$ babel --version 
6.2.0 (babel-core 6.2.1) 

$ cat .babelrc 
{ 
    "presets": ["es2015", "stage-1"] 
} 

$ babel-doctor 

Babel Doctor 
Running sanity checks on your system. This may take a few minutes... 

✔ Found config at /path/to/.babelrc 
✔ No duplicate babel packages found 
✔ All babel packages appear to be up to date 
✔ You're on npm >=3.3.0 

Everything looks all right! 
+0

'new.target.properties'? – sjrd

+0

似乎更清楚的是讓子類重寫構造函數並將屬性傳遞給我,但是'new.target'就是這樣做的方式,不幸的是它沒有被Babel轉換。 – loganfsmyth

+0

我只是檢查'new.target'。它僅在Node 5.0中可用。 Chrome和FireFox顯示我的錯誤。而且,BabelJS不會將'new.target'轉換成ES5。我使用了'es2015'預設。 – vbarbarosh

回答

0

將溶液下列:

  1. 粘到new.target通過@sjrd@loganfsmyth提示:

    class ObjectModel extends Model 
    { 
        static properties = {}; 
    
        constructor(value) { 
         super(_.extend({}, new.target.properties, _.pick(value, _.keys(new.target.properties)))); 
        } 
    } 
    
  2. 創建,其將一個transpiler全部爲new.target(ES6)爲this.constructor(ES5):

    function transpileNewTarget() 
    { 
        return { 
         visitor: { 
          MetaProperty(path) { 
           if (path.isMetaProperty() && path.node.meta.name == 'new' && path.node.property.name == 'target') { 
            path.replaceWithSourceString('this.constructor'); 
           } 
          } 
         } 
        }; 
    }