在Javascript中返回类的类静态getter

时间:2017-12-05 17:49:05

标签: javascript ecmascript-6 webstorm es6-class

我有一些代码:

//Main class
class Tools { 

  //Subclass implemented by static getter 
  static get SUPPORTED_UNITS () {
    return class {  
      //Another one
      static get Size () {
        return class {
          //Some data (constants in my case)
        };
      }
    };
  }
}

我想像Tools.SUPPORTED_UNITS.Size一样使用它,我希望收到一些数据。 我使用WebStorm编写JavaScript代码,因此当我尝试使用它时它会向我显示。

Screenshot of error

我不确切地知道,也许我还没有为我的WebStorm做过一些设置,但是......我需要做的是我可以使用像Class.Subclass.SubClassMethod/SubSubclass那样的构造。

我需要:

  • 这不是方法
  • 这是静态的
  • 它是不可变的(没有Object.freeze或类似的东西) - 因此我无法通过键入Class.Subclass
  • 来更改Class.Subclass = foo;
  • 它是由IDE编制索引的 - 所以我得到了IDE的一些帮助(比如我输入Class.Su,她建议Class.Subclass

在ES6和WebStorm中是否真实?或者也许我必须使用ES7和Babel或类似的东西?

P.S。该代码正在运行,但我需要IDE的建议,否则它就像地狱一样。

1 个答案:

答案 0 :(得分:0)

关注@estus和@Felix Kling建议......(可能在这里被误传)

const TOOLS = {
    get SUPPORTED_UNITS() {
        return {
            get SIZE() {
                return {
                    get Bar() { 
                        return 1;
                    }
                }
            }
        }
    }
};
console.log(TOOLS.SUPPORTED_UNITS.SIZE.Bar) // 1;

TOOLS.SUPPORTED_UNITS.SIZE = "Hello";
// TOOLS.SUPPORTED_UNITS.SIZE = "Hello";
//                            ^
// TypeError: Cannot set property SIZE of #<Object> which has only a getter

这是有效的,但正如@bergi所说,它在每次查找中都会创建一个新对象:

console.log(TOOLS.SUPPORTED_UNITS === TOOLS.SUPPORTED_UNITS); // false

是的...

仍在使用getter的替代方法是将所有这些对象封装在IIFE中:

const TOOLS = (function () {
    const SIZE = {
        get Bar() { return 1; }
    }
    const SUPPORTED_UNITS = {
        get SIZE() {
            return SIZE;
        }
    }
    return {
        get SUPPORTED_UNITS() {
            return SUPPORTED_UNITS;
        }
    }
}());

console.log(TOOLS.SUPPORTED_UNITS.SIZE.Bar === TOOLS.SUPPORTED_UNITS.SIZE.Bar); // true
console.log(TOOLS.SUPPORTED_UNITS.SIZE === TOOLS.SUPPORTED_UNITS.SIZE);  // true
console.log(TOOLS === TOOLS); // true

TOOLS.SUPPORTED_UNITS = "hello"; // still throws an error
  

第三次更新:

第二个示例解决了与每次查找创建新对象相关的问题,但它也没有考虑到对每个嵌套属性的访问都会导致函数调用重新评估不应该更改的内容:

//A naive measurement:
for(let counter = 0; counter < 5; counter++) {
    let start = Date.now();    
    for(let i = 0; i < 200000; i++){
        let somevar = Tools.SUPPORT_UNITS.SIZE;
    }
    let end = Date.now();
    console.log(`Elapsed using nested getters: ${end - start}ms.`);
}
// Something like:
/** Elapsed using nested getters: 20ms.
 * Elapsed using nested getters: 14ms.
 * Elapsed using nested getters: 9ms.
 * Elapsed using nested getters: 10ms.
 * Elapsed using nested getters: 10ms.
 *
 // While the same as ordinary properties:
 * Elapsed ordinary properties: 2ms.
 * Elapsed ordinary properties: 5ms.
 * Elapsed ordinary properties: 1ms.
 * Elapsed ordinary properties: 0ms.
 * Elapsed ordinary properties: 0ms.
 */

因此,如果在可预见的未来运行200000次循环,那么在使用此方法之前检查替代方案也会更好。