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

Ale*_*nik 5 node.js express sequelize.js

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

例子

function get_instance_methods(sequelize) {
  return {
    is_admin : function() {
      return this.admin === true;
    },
  };
};
Run Code Online (Sandbox Code Playgroud)

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

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;
};
Run Code Online (Sandbox Code Playgroud)

但现在我遇到了一个mixin被定义的东西,然后像这样在模态HERE中被使用。

 withCompanyAwareness.call ( instance_methods, sequelize ) ;
Run Code Online (Sandbox Code Playgroud)

其本身的代码mixin正在此处定义。可以在下面找到 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']
      ]
    });
  };

};
Run Code Online (Sandbox Code Playgroud)

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

Ion*_*zău 2

非常有趣的问题!让我们从目前已经明确的内容开始:

  • 模型应始终返回模型实例
  • 创建模型实例,在这两种情况下都instanceMethods被设置为包含方法的对象。

get_instance_methods(sequelize)在这两种情况下都返回函数对象。在第一个示例中,该对象未使用新功能进行扩展。返回的函数将传递给模型创建,因此get_instance_methods(...)返回的内容将到达模型的instanceMethods.

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

instance_methods.myNewMethod = function () { ... }
Run Code Online (Sandbox Code Playgroud)

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

现在,假设我们有第三个模型,需要myNewMethod以同样的方式进行精确计算。在这种情况下,我们有两个选择:在第二个和第三个模型中复制该myNewMethod函数,最终得到重复的代码,这并不有趣,或者创建一个 mixin

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

因此,我们可以有一个 mixin 函数,称为:

function with_my_new_method () {
    this.myNewMethod = function () { ... }
} 
Run Code Online (Sandbox Code Playgroud)

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

// 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
});
Run Code Online (Sandbox Code Playgroud)

当使用 调用with_my_new_methodmixin 函数时.call,这意味着我们将 as 上下文传递instance_methods给函数。因此,instance_methods将成为thismixin 函数的内部。

结论

在这种情况下,mixin 函数充当实用函数,用新方法扩展实例方法对象。