【问题标题】:Sequelize classMethods vs instanceMethods续集 classMethods 与 instanceMethods
【发布时间】:2026-01-19 07:55:02
【问题描述】:

所以开始我对 Node.js 的所有事物的冒险。我正在尝试学习的工具之一是 Sequelize。所以我将开始我想做的事情:

'use strict';
var crypto = require('crypto');

module.exports = function(sequelize, DataTypes) {
  var User = sequelize.define('User', {
    username: DataTypes.STRING,
    first_name: DataTypes.STRING,
    last_name: DataTypes.STRING,
    salt: DataTypes.STRING,
    hashed_pwd: DataTypes.STRING
  }, {
    classMethods: {

    },
    instanceMethods: {
      createSalt: function() {
        return crypto.randomBytes(128).toString('base64');
      },
      hashPassword: function(salt, pwd) {
        var hmac = crypto.createHmac('sha1', salt);

        return hmac.update(pwd).digest('hex');
      },
      authenticate: function(passwordToMatch) {
        return this.hashPassword(this.salt, passwordToMatch) === this.hashed_pwd;
      }
    }
  });
  return User;
};

我对何时使用 classMethodsinstanceMethods 感到困惑。当我想到createSalt()hashPassword() 时,对我来说应该是类方法。它们是通用的,并且在大多数情况下与它们通常使用的特定实例没有任何关系。但是当我在classMethods 中有createSalt()hashPassword() 时,我无法从instanceMethods 调用它们。

我尝试了以下变体:

this.createSalt();
this.classMethods.createSalt();
createSalt();

像下面这样的东西不起作用,我可能只是不理解一些简单的东西。

authenticate: function(passwordToMatch) {
  console.log(this.createSalt());
  return this.hashPassword(this.salt, passwordToMatch) === this.hashed_pwd;
}

非常感谢任何提示/提示/方向!

【问题讨论】:

    标签: javascript node.js orm sequelize.js


    【解决方案1】:

    所有不修改或检查任何类型实例的方法都应为classMethod,其余为instanceMethod

    例如:

    // Should be a classMethods
    function getMyFriends() {
      return this.find({where{...}})
    }
    
    // Should be a instanceMethods
    function checkMyName() {
      return this.name === "george";
    }
    

    【讨论】:

    • 这对我来说是有道理的,这就是我所想的,所以像 makeSalt() 和 hashPassword() 这样的通用函数应该是类方法,因为它们实际上与特定实例无关。所以现在说我真正的问题是我无法在我的 instanceMethod 中调用 classMethond 并且不确定交易是什么。
    • 我加入了 IRC,他们能够帮助我。它与我在其他语言中使用的有点不同,但这只是学习过程的一部分!因为它是一个类方法,所以它只是模型的一部分,所以你不必使用像“this”这样的东西。您只需将其称为“User.getSalt()”,因此现在一切正常!
    • 感谢您的帮助!
    【解决方案2】:

    虽然基础是当你想修改你的instance (ergo row) 时应该使用instance 方法。我宁愿不使用不使用class(因此表格)本身的方法污染classMethods

    在您的示例中,我会将hashPassword 函数放在您的类之外,并将其作为辅助函数保留在我的实用程序模块中的某个位置(或者为什么不是同一个模块,而是作为正常定义的函数)......就像

    var hashPassword = function(...) { ... }
    
    ...
    
    ...
    
      instanceMethods: { 
         authenticate: function( ... ) { hashPassword( ... ) }
      }
    

    【讨论】:

    • 我也想这样做。我想我会继续这样做只是为了养成这样做的习惯。我无法决定是否将其分开,因为我只会在用户模型中使用 hashPassword。
    【解决方案3】:

    从 sequelize 3.14 开始,我发现这对我有用

    var myModel = sequelize.define('model', {
    
    }, {
      classMethods: {
        someClassMethod: function() {
          return true;
        }
    }, {
      instanceMethods: {
        callClassMethod: function() {
          myModel.someClassMethod();
        }
      }
    });
    

    【讨论】: