admin管理员组

文章数量:1291236

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:

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

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.

So I might do this:

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?

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:

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

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.

So I might do this:

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?

Share Improve this question asked Dec 9, 2015 at 23:57 HudHud 1131 silver badge6 bronze badges 3
  • 1 What is parent.extend? And how does instanceof work there? Is there new? – elclanrs Commented Dec 10, 2015 at 0:00
  • Sorry, should have been more clear. I'm assuming some sort of Backbone-esque prototypical inheritence for brevity. – Hud Commented Dec 10, 2015 at 0:07
  • 2 Does checkType need to be in that main parent file? Seems like all this would be resolved if you put it in a different file. – loganfsmyth Commented Dec 10, 2015 at 0:09
Add a ment  | 

2 Answers 2

Reset to default 7

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:

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:

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

I don't know exactly what extend is doing here. 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. I'll often do something like this:

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

If you don't want to use classes, maybe want a more FP style. You could make parent a function:

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

本文标签: javascriptES6 circular dependencyStack Overflow