ES6循环依赖

11

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

我的设置如下:

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 中添加一个函数,用于检查对象是否是 ab 的实例。

所以我可能会这样做:

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'
    }
  }
}

这是一个循环依赖关系。有没有一种优雅的方式来处理它?


1
parent.extend是什么?instanceof在那里如何工作?有new吗? - elclanrs
抱歉,我应该更清楚。出于简洁起见,我假设采用了类似于Backbone的原型继承。 - Hud
2
checkType需要在主文件中吗?如果将其放在另一个文件中,所有这些问题似乎都会得到解决。 - loganfsmyth
2个回答

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 是做什么的。我猜测它是某种子类化机制。

一般来说,虽然在确实需要时有应对循环导入依赖的方法,但这些依赖通常意味着你代码结构存在问题。


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');
    }
}

如果您不想使用类,可能更倾向于函数式编程风格。您可以将parent作为一个函数: 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' })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接