访问 Coffeescript 中的静态属性



牢记以下代码

A.咖啡

B = require './b'
C = require './c'
console.log B.someStaticVar
C.checkB()

B.咖啡

C = require './c'
class B
@someStaticVar: 1
module.exports = B;

C.咖啡

B = require './b'
class C
@checkB: ->
console.log B.someStaticVar
module.exports = C

我试图理解为什么b的静态属性在被 c访问时未定义,但在被a访问时返回1

输出:

$ coffee a.coffee
1
undefined

看起来你有一个循环引用。

  1. A 加载 B
  2. B 加载 C
  3. C 加载 B
    • 但是 B 还没有完成加载,所以这里它是一个空对象
  4. C 完成加载
  5. B 完成加载
  6. A 加载 C - 它已经加载,所以它只是得到一个引用。
  7. 加载完成后,将执行文件末尾的console.log行。

以下是您的 3 个模块的一个版本,可以更好地说明这一点:

A.咖啡

B = require './b'
C = require './c'
console.log B.someStaticVar
C.checkB()

B.咖啡

C = require './c'
console.log 'in b.coffee, we have loaded C: ', C
class B
@someStaticVar: 1
module.exports = B;

C.咖啡

B = require './b'
console.log 'in c.coffee, we have loaded B: ', B
class C
@checkB: ->
console.log B.someStaticVar
module.exports = C

在 commonjs 中,您有两种选择来修复此循环依赖关系:

1. 延迟加载

在执行函数之前,不需要c.coffee./b。当您在a.coffee中调用C.checkB时,B 将已完全加载,并且将从 require 调用返回正确的类

class C
@checkB: ->
B = require './b'
console.log B.someStaticVar
module.exports = C

2. 重构

BC紧密结合。考虑将它们重写为包含在单个文件中。您可以从b.coffee中删除require './c'。虽然我猜它在这个例子中,因为你的代码更复杂并且确实需要它。

A.咖啡

{ B, C } = require './b'
console.log B.someStaticVar
C.checkB()

B.咖啡

class B
@someStaticVar: 1
class C
@checkB: ->
console.log B.someStaticVar
module.exports = 
C: C
B: B

最新更新