【问题标题】:ES6 circular dependencyES6 循环依赖
【发布时间】:2015-12-09 23:57:04
【问题描述】:

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

所以我有这样的设置:

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

现在这是一个循环依赖。有没有优雅的方法来处理这个问题?

【问题讨论】:

  • 什么是parent.extendinstanceof 在那里是如何工作的?有new吗?
  • 对不起,应该更清楚。为简洁起见,我假设某种 Backbone 式的原型继承。
  • checkType 是否需要在该主父文件中?如果你把它放在不同的文件中,似乎这一切都会得到解决。

标签: javascript ecmascript-6 circular-dependency commonjs


【解决方案1】:

在知道子类的父类中有逻辑是一种严重的反模式。相反,在返回类型的子类中添加方法。比如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() 调用。我会经常做这样的事情:

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

    【讨论】:

      猜你喜欢
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 2010-09-12
      • 2021-10-02
      • 1970-01-01
      相关资源
      最近更新 更多