牢记以下代码
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
看起来你有一个循环引用。
- A 加载 B
- B 加载 C
- C 加载 B
- 但是 B 还没有完成加载,所以这里它是一个空对象
- C 完成加载
- B 完成加载
- A 加载 C - 它已经加载,所以它只是得到一个引用。
- 加载完成后,将执行文件末尾的
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. 重构
B
和C
紧密结合。考虑将它们重写为包含在单个文件中。您可以从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