Nodejs中express这样写代码合理吗

Nodejs中express这样写代码合理吗

今天看了一下express4.x的代码发现这样的代码

var proto = module.exports = function(options) {
  options = options || {};

  function router(req, res, next) {
    router.handle(req, res, next);
  }

  // mixin Router class functions
//看这里,router的__proto__应该指向一个Function.prototype,这样router一覆盖,和object.extend有什么区别?
//这样有没有违反原型链
  router.__proto__ = proto; 

  router.params = {};
  router._params = [];
  router.caseSensitive = options.caseSensitive;
  router.strict = options.strict;
  router.stack = [];

  return router;
};

刚查了一下资料,这种语法是不提倡使用的,router通过原型链可以找到proto的函数,也不知道为啥不提倡,求大神解答,object.extend 是进行一次复制


3 回复

在Node.js中使用Express框架时,上述代码片段展示了如何定义一个路由处理程序。但是,直接修改router.__proto__并不是最佳实践。这是因为直接修改原型链可能会导致一些不可预见的问题,并且不符合现代JavaScript的最佳实践。

示例代码

假设我们想创建一个自定义的路由处理器,并且希望它具有某些默认的行为。我们可以使用类(class)来实现这一点,这不仅更符合现代JavaScript的标准,而且也更加清晰和易于维护。

const express = require('express');
const app = express();

class CustomRouter {
  constructor(options = {}) {
    this.params = {};
    this._params = [];
    this.caseSensitive = options.caseSensitive;
    this.strict = options.strict;
    this.stack = [];
  }

  handle(req, res, next) {
    // 处理请求逻辑
    next();
  }
}

const router = new CustomRouter({ caseSensitive: false, strict: true });

// 将handle方法绑定到Express应用
app.use(router.handle.bind(router));

// 启动服务器
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

解释

  1. 使用类(Class)

    • 使用类是一种更现代、更清晰的方式来组织代码。类提供了更好的封装性和可读性。
  2. 构造函数

    • 构造函数用于初始化对象的状态。在这个例子中,我们设置了caseSensitivestrict等选项。
  3. handle 方法

    • handle 方法是一个普通的实例方法,用于处理请求。你可以在这里添加任何你需要的逻辑。
  4. 使用 .bind() 方法

    • 我们使用.bind(router)来确保handle方法内部的this关键字指向router实例,从而能够访问到它的属性。

总结

直接修改__proto__并不是一个推荐的做法,因为它破坏了原型链的预期行为,可能导致难以追踪的错误。通过使用类和构造函数,可以使代码更加模块化、可读性强,并且更容易维护。


关于您提到的代码片段,确实存在一些潜在问题。首先,router.__proto__ 这种写法并不是最佳实践,因为它直接修改了对象的原型链。这可能会导致一些难以调试的问题,并且不利于代码的可维护性和清晰度。

示例代码

var express = require('express');
var router = express.Router();

// 更推荐的做法是直接将方法挂载到 router 上
router.get('/', function (req, res) {
  res.send('Hello World!');
});

module.exports = router;

解释

  1. 避免直接修改 __proto__

    • 直接修改 __proto__ 会破坏原型链的结构,使得代码难以理解和维护。
    • 推荐使用对象的 extend 方法或者直接将方法挂载到对象上,如上面的示例。
  2. 推荐使用 express.Router()

    • Express 提供了一个内置的 Router 类,你可以直接实例化并使用它来处理路由。
    • 如上述代码所示,我们使用 express.Router() 来创建一个路由对象,然后定义路由处理函数。
  3. 代码可读性和可维护性

    • 通过直接将方法挂载到路由对象上,代码更加直观,易于阅读和维护。
    • 不推荐直接修改原型链,因为这会导致潜在的 bug 和性能问题。

希望这些解释能帮助您理解为什么这种写法不太合理,并提供了一种更合理的替代方案。

回到顶部