ES6循环依赖

时间:2015-12-09 23:57:04

标签: javascript ecmascript-6 circular-dependency commonjs

这是我经常遇到的问题,我希望找到正确的方法来处理它。

所以我有这样的设置:

parent.js

export default {
  x: 1
}

a.js

import parent from 'parent.js'
export default parent.extend(a, { title: 'a' })

b.js

import parent from 'parent.js'
export default parent.extend(b, { title: 'b' })
很酷,现在我有了一些孩子。 但我决定在parent.js中有一个函数来检查对象是否是 a b 的实例。

所以我可能会这样做:

parent.js

import a from 'a'
import b from 'b'

export default {
  x: 1,
  checkType (obj) {
    if (obj instanceof a) {
      return 'a'
    } else if (obj instanceof b) {
      return 'b'
    }
  }
}

那么现在这是一个循环依赖。是否有一种优雅的方式来处理这个问题?

2 个答案:

答案 0 :(得分:7)

在父类中具有知道子类的逻辑是一种严重的反模式。而是在返回类型的子类中添加方法。例如,在a.js

import parent from 'parent.js';
export default parent.extend(a, { title: 'a', checkObj() { return 'a'; }});

如果checkObj的所需回报始终是title属性的值,那么当然只是:

// parent.js
export default {
  x: 1,
  checkObj() { return this.title; }
}

我不确切知道extend在这里做了什么。我假设它是某种子类化机制。

一般来说,循环导入依赖关系虽然有真正必要的方法可以处理它们,但宇宙试图告诉你,你的代码构造方式有问题。

答案 1 :(得分:2)

如果您能够使用es6类,那么您可以利用构造函数中的super()调用。我经常做这样的事情:

Parent.js

export default class {
    constructor(options, child) {
        this.child = child;
        this.x = 1;
    }

    checkType() {
        return this.child;
    }
}

A.js

import Parent from './Parent';  

export default class extends Parent {
    constructor(options) {
        super(options, 'a');
    }
}

B.js

import Parent from './Parent';  

export default class extends Parent {
    constructor(options) {
        super(options, 'b');
    }
}

如果您不想使用课程,可能需要更多FP风格。你可以让父母成为一个职能:

parent.js

export default function(child) {
    return {
        x: 1,
        checkType (obj) {
            return child; 
        }
        extend (something) {
            // assuming the returns something as you said
        }
    }
}

a.js

import parent from 'parent.js'
export default parent('a').extend(a, { title: 'a' })

b.js

import parent from 'parent.js'
export default parent('b').extend(b, { title: 'b' })