8

介绍:

我有一些创建单例的遗留代码:

define(['backbone', 'MyModel'], function (Backbone, MyModel) {

  var MyCollection = Backbone.Collection.extend({
    model: MyModel,
    initialize: function () {
      //...
    }
  });

  return new MyCollection();
});

出于测试目的,我需要生成新实例以将它们作为依赖项注入。

问题:

有没有办法在不修改原始代码的情况下生成单例的新实例?

我做了什么:

我提出了一个解决方案:将类添加为实例的属性

    initialize: function () {
      this.ClassObject = MyCollection;
      //...
    }

然后实例化它

var myCollection = require('myCollection');
var myCollectionInstance = new myCollection.ClassObject();

这个解决方案修改了类,我想避免它。

我还尝试创建单例的副本:

function generateNewCollection() {
  var F = function () {};
  F.prototype = myCollection;
  return new F();
}

它会生成一个新实例,但不会创建其依赖项的新实例,因此对于下一次测试,环境仍然很脏。

4

2 回答 2

2

解决方案:使用原型中的构造函数。

var newMyCollection = new (Object.getPrototypeOf(myCollection).constructor);
于 2013-07-11T13:42:28.823 回答
-1

将类定义添加为实例的属性是我发现解决此问题的唯一方法。您可能希望标准化Klass为属性名称,这似乎是人们的方式。这个解决方案可能感觉有点脏,但至少对我来说效果很好。

由于我注意到您使用的是模块模式,因此另一个增强功能是让模块返回一个实例。通过这种方式,它会为您管理单例模式,因为它只会包含每个依赖项一次。

看起来是这样的:

define ['models/sprockets'],(Sprocket) ->
  MyCollection = Backbone.Collection.extend
    model: Sprocket
    initialize: -> console.log 'initialized'
  myCollection = new MyCollection()
  myCollection.Klass = MyCollection
  return myCollection # If managed by requireJs or curl, this module will always return you the same singleton and will have the class available on the `Klass` property
于 2013-07-10T17:41:15.710 回答