You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何模拟Express.js兼具函数调用与对象属性访问的行为?

如何模拟Express.js的对象行为

先明确两个JS核心特性:

  • Object instanceof Function:因为Object本身是构造函数,属于Function类型
  • Function instanceof Object:因为函数在JS里本质也是对象,可直接为其添加属性

问题描述

我们需要模拟Express的特殊行为:既能当作函数调用创建实例,又能当作对象访问自身属性方法:

const express = require("express");
const app = express(); // 作为函数调用,生成app实例
app.use(express.json()) // 作为对象,访问其json属性方法

这种行为既不是普通函数(无法直接挂载属性),也不是类(无需new即可调用),更不是普通对象(不能直接执行调用)。

我的三次尝试

尝试1:用函数模拟

// 尝试用函数模拟
var express = () => { 
  this.json = () => {console.log("json")}
  return {
    listen : () =>{ console.log("listen !") },
    use    : () =>{ console.log("use !")  }
  }
}

const app = express(); // 正常
      app.listen();    // 正常
      app.use();       // 正常

express.json(); // 失败

问题:箭头函数内的this指向错误,且未给express函数本身挂载json属性,无法直接调用express.json()。

尝试2:用类模拟

// 尝试用类模拟
class express{
  constructor(){
    return {
      listen : () => { console.log("listen !") },
      use    : () => { console.log("use !")  }
    }
  }
  json(){console.log("json")}
}

const app = express(); // 报错:Class constructor express cannot be invoked without 'new'
app.listen();  
app.use();
      
express.json(); // 未实例化,无法调用

问题:类必须通过new关键字调用,不符合Express的调用方式;且未给json添加static修饰,无法通过类本身调用。

尝试3:用对象模拟

// 尝试用对象模拟
var express = {
    constructor : ()=>{ // 无法覆盖构造函数
      return {
          listen : () =>{ console.log("listen !") },
          use    : () =>{ console.log("use !")  }
      }
    },
    json : ()=>{console.log("json")}
  }
  
const app = express(); // 报错:Uncaught TypeError: express is not a function
      app.listen();    
      app.use();       
express.json()

问题:普通对象无法直接作为函数调用,必须是函数类型才能被()执行。

正确的模拟方法

利用JS中函数也是对象的特性,先定义一个函数,再直接给该函数添加属性(包括方法):

// 正确模拟Express行为的实现
function express() {
  // 返回app实例,包含listen、use等方法
  return {
    listen: () => { console.log("listen !") },
    use: (middleware) => { 
      console.log("use middleware !");
      if (middleware) middleware();
    }
  };
}

// 给express函数本身添加json属性(方法)
express.json = () => {
  console.log("json middleware called");
  // 可返回实际中间件逻辑,比如解析JSON的处理函数
  return () => {};
};

// 测试调用
const app = express();
app.listen(); // 输出:listen !
app.use(express.json()); // 输出:json middleware called → use middleware !
express.json(); // 输出:json middleware called

原理说明

  1. express本身是普通函数,因此可以直接通过express()调用,返回app实例对象。
  2. 由于函数在JS中是Object类型的实例(Function instanceof Object为true),所以能直接给express函数挂载属性和方法,实现像访问对象属性一样调用express.json()的效果。

内容的提问来源于stack exchange,提问作者Ionut Eugen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:35:21