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

JavaScript:函数为何可拥有属性?exports作为函数添加属性的原理

为什么JavaScript中函数类型的exports可以添加属性?

这是我遇到的一个代码片段,当obj.exports被赋值为函数类型后,我仍然可以给它添加hello属性,这让我有点困惑,因为通常我们都是给对象类型的exports添加属性。

代码片段:

const obj = { exports: {} }
obj.exports = () => { console.log('invoked') }
obj.exports.hello = () => { console.log('hello() invoked') }
var output = `type of obj => ${typeof obj} #### type of obj.exports => ${typeof obj.exports} #### obj.exports.hello() is ${typeof obj.exports.hello} `;
console.log(output);

输出结果:

type of obj => object #### type of obj.exports => function #### obj.exports.hello() is function

我的疑问是:通常exports为object类型时,添加属性很合理,但为什么当exports本身是function类型时,还能拥有属性呢?


嘿,这个问题问得特别好!核心原因其实是在JavaScript里,函数本质上是一种特殊的对象——准确来说是Function对象的实例。

你应该听过JavaScript里"函数是一等公民"的说法,这意味着函数不仅能像普通函数那样被调用,还能完全像对象一样拥有自己的属性和方法。这是因为函数在底层继承自Object,天然具备对象的所有特性:可以添加/删除属性、可以作为参数传递、也能被赋值给变量。

回到你的代码里拆解一下:

  1. 一开始obj.exports是个空对象,后来你把它重新赋值成了一个箭头函数() => { console.log('invoked') }。
  2. 当你执行obj.exports.hello = ...时,你其实是在给这个函数对象添加一个名为hello的属性,操作逻辑和给普通对象加属性完全一致。
  3. 这时候obj.exports本身还是个可调用的函数(所以typeof返回function),但它同时拥有了hello这个函数属性——你完全可以分开调用它们:
    • obj.exports()会执行原函数,打印invoked
    • obj.exports.hello()会执行你添加的属性函数,打印hello() invoked

这种特性在JavaScript里其实很常见,比如你可能见过给函数添加静态属性的场景:

function MyTool() {}
MyTool.version = "1.0.0";
console.log(MyTool.version); // 输出 "1.0.0"

这和你代码里给obj.exports添加hello属性是同一个逻辑。

总结一下:函数在JavaScript中既是可执行的函数体,也是一个标准对象,所以你可以给它添加任意属性,这完全符合语言的设计逻辑~

内容的提问来源于stack exchange,提问作者Amirhosein Al

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:20:39