在sequilizejs中定义一个mixin而不是一个实例方法有什么用?

What is the use of defining a mixin instead of a instance method in sequilizejs?

我正在尝试通过一些用于重构 sequilize.js 模型的高级技术,并发现了如何使用 instanceMethods 方法以及如何将 util 函数附加到它。

例子:

function get_instance_methods(sequelize) {
  return {
    is_admin : function() {
      return this.admin === true;
    },
  };
};

然后上面的可以这样使用:

module.exports = function(sequelize, DataTypes) {

  var instance_methods = get_instance_methods(sequelize);

  var User = sequelize.define("User", {
      email : {
          type      : DataTypes.STRING,
          allowNull : false
      },
  }, {
      instanceMethods : instance_methods,
    });

    return User;
};

但现在我遇到了一个 mixin 被定义然后在模态 HERE 中被使用。

 withCompanyAwareness.call ( instance_methods, sequelize ) ;

正在定义 mixin 本身的代码 HERE。可以在下面找到 mixin 的快照:-

module.exports = function(sequelize){
  // more methods defined here .. just adding a snapshot here.
  this.get_company_with_all_leave_types = function() {
    return this.getCompany({
      include : [{
        model : sequelize.models.LeaveType,
        as    : 'leave_types',
      }],
      order : [
        [{ model : sequelize.models.LeaveType, as : 'leave_types' }, 'sort_order', 'DESC'],
        [{ model : sequelize.models.LeaveType, as : 'leave_types' }, 'name']
      ]
    });
  };

};

定义 mixin 与使用实例方法的目的到底是什么?为什么需要定义 mixin?

非常有趣的问题!让我们从目前清楚的内容开始:

  • 模型应该return模型实例总是
  • 创建 Model 实例,在这两种情况下 instanceMethods 都被设置为包含方法的对象。

get_instance_methods(sequelize) return在这两种情况下都是函数的对象。在第一个示例中,此对象未扩展新功能。 returned 的函数被传递给模型创建,因此,到达模型的 instanceMethods.

get_instance_methods(...) returns

如果需要,我们可以在 将 instance_methods 对象发送到模型之前修改 对象:

instance_methods.myNewMethod = function () { ... }

这将在添加此功能的特定模型的实例函数中添加 myNewMethod,但不会在我们调用 get_instance_methods 的其他模型中添加。

现在,假设我们有第三个模型,需要以同样的方式 myNewMethod 精确。在那种情况下,我们有两个选择:在第二个和第三个模型中复制 myNewMethod 函数,以重复的代码结束,这并不好玩,或者 创建一个 mixin

在这种情况下,mixin 是什么?只是 统一 最终重复代码的函数。

因此,我们可以有一个 mixin 函数叫做:

function with_my_new_method () {
    this.myNewMethod = function () { ... }
} 

因此,在模型中我们将有:

// Model1.js:
var instance_methods = get_instance_methods(sequelize);
var Model1 = sequelize.define("Model1", {
  ...
}, {
  instanceMethods: instance_methods
});

// Model2.js:
var instance_methods = get_instance_methods(sequelize);
with_my_new_method.call(instance_methods)
var Model2 = sequelize.define("Model2", {
  ...
}, {
  instanceMethods: instance_methods
});

// Model3.js:
var instance_methods = get_instance_methods(sequelize);
with_my_new_method.call(instance_methods)
var Model3 = sequelize.define("Model3", {
  ...
}, {
  instanceMethods: instance_methods
});

当使用 .call 调用 with_my_new_method mixin 函数时,这意味着我们将 instance_methods 作为上下文传递给函数。因此,instance_methods 将在 mixin 函数内部变为 this

结论

在这种情况下,mixin 函数作为实用函数工作,使用新方法扩展 实例方法对象。