简体   繁体   English

ES6循环依赖

[英]ES6 circular dependency

This is an issue I run into fairly frequently, and I was hoping to discover the correct way to handle it. 这是我经常遇到的一个问题,我希望找到正确的方法来处理它。

So I have a setup like this: 所以我有这样的设置:

parent.js : parent.js

export default {
  x: 1
}

a.js : a.js

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

b.js : b.js

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

Cool, now I've got some children. 很酷,现在我有了一些孩子。 But I decide I would like to have a function in parent.js that checks if an object is an instance of a or b . 但我决定在parent.js中有一个函数来检查对象是否是ab的实例。

So I might do this: 所以我可能这样做:

parent.js : 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'
    }
  }
}

Well now that's a circular dependency. 那么现在这是一个循环依赖。 Is there an elegant way to handle this? 有一种优雅的方式来处理这个问题吗?

Having logic in the parent class that is aware of the subclasses is a serious anti-pattern. 在父类中具有知道子类的逻辑是一种严重的反模式。 Instead, add methods in the subclasses that return the type. 而是在返回类型的子类中添加方法。 for instance, in a.js : 例如,在a.js

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

If the desired return from checkObj is always the value of the title property, then of course just: 如果checkObj的所需返回始终是title属性的值,那么当然只是:

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

I don't know exactly what extend is doing here. 我不知道到底是什么extend是在这里做。 I'm assuming it is some kind of subclassing mechanism. 我假设它是某种子类化机制。

In general, circular import dependencies, although there are ways to deal with them when truly necessary, are the universe trying to tell you that there is something wrong with the way you've structured your code. 一般来说,循环导入依赖关系虽然有真正必要的方法来处理它们,但是宇宙试图告诉你构造代码的方式有问题。

If you're able to use es6 classes, then you can take advantage of the super() call in the constructor. 如果你能够使用es6类,那么你可以利用构造函数中的super()调用。 I'll often do something like this: 我会经常这样做:

Parent.js Parent.js

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

    checkType() {
        return this.child;
    }
}

A.js A.js

import Parent from './Parent';  

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

B.js B.js

import Parent from './Parent';  

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

If you don't want to use classes, maybe want a more FP style. 如果您不想使用类,可能需要更多FP样式。 You could make parent a function: 你可以让父母成为一个职能:

parent.js parent.js

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

a.js a.js

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

b.js b.js

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM