当两者都在闭包

时间:2017-06-28 15:38:57

标签: javascript function class object closures

我还在学习关闭,所以鉴于它们的性质,这可能是不可能的,所以请耐心等待。我有一个全局变量,它是一个从闭包返回的对象。这个对象的一些属性是类。

var TEST = (function() {
    return {
        Base: class {
            constructor() {}
            hello() { console.log("Hello"); }
        },
        Extended: class { // what do I do here?
            constructor() {}
        }
    }
})();

我可以声明var b = new TEST.Base()并在该var上调用hello()函数,按预期工作。

我想TEST.Extended扩展TEST.Base并可以访问自己的hello()函数,到目前为止还没有任何运气。我试过了这件事:

// 1 - ReferenceError: Base is not defined
Extended: class extends Base {...}

// 2 - TypeError: TEST is undefined
Extended: class extends TEST.Base {...}

// 3 - ReferenceError: NamedClass is not defined
Base: class NamedClass {...},
Extended: class OtherNamedClass extends NamedClass {...}

// 4 - TypeError: TEST is undefined
Base: class NamedClass {...},
Extended: class OtherNamedClass extends TEST.NamedClass {...}

我不确定任何其他选择。这可能在Javascript中吗?

1 个答案:

答案 0 :(得分:0)

这里有多个问题。

首先,如果您使用的类意味着您声明的文件几乎肯定被视为模块,则意味着顶级变量不会在文件外自动显示已定义。您必须import TEST或执行window.TEST = (function(){...之类的操作。说到你的函数包装器......

虽然IIFE确实创造了一个与任何方式无关的闭包,因为你不会关闭任何东西:正如你已经写过的那样,包装器毫无意义。

var TEST = {
  Base: class { /* definition goes here */ }
};

和你写的一样。为了使闭包具有任何实用程序,您需要隐藏中的某些内容。

var TEST = (function() {
  var private = whatever;
  return {
    Base: class {}
  };
})();

return ed对象关闭私有。

现在转到实际的问题。

如何将扩展类作为TEST对象的一部分导出。简短回答: 你不能这样做。它需要引用TEST.Base,你不能以这种方式在对象定义中做到这一点。有几种选择,但如果您不希望Base暴露,我可以使用以下内容:

var TEST = (function() {
  var Base = class { /* class definition goes here */ };
  return {
    Base,
    Extended: class extends Base { /* extension definition goes here */ }
  };
})();

请注意,这仍然有点不必要。你可以轻松地写

var Base = class {};
var TEST = { Base, Extended: class extends Base {} };

事实上现在我们有ES 6模块(或者可以可靠地伪造它们),这确实是应该编写的(IMHO)。您可以决定是单独导出Base还是仅通过API对象TEST访问它。