我已经使用JS几个月了,我偶然发现了这个有趣的(至少对我来说)的事情。
看看这段代码:
class myClass
{
constructor()
{
this.x = 0;
}
}
function myFunc(){}
myClass.myFunc = myFunc;
我可以调用myClass.myFunc()
,但myClass只是一个函数。事实上,我可以把它改写为
function myClass()
{
this.x = 0;
}
它的行为是一样的,我仍然可以打电话给myClass.myFunc()
.那么实际上什么是函数(比如"引擎盖下")?它的行为似乎更像是一个对象,如果它有任何意义,可以调用它,从而能够拥有自己的字段。
另外,这被认为是不好的做法吗? 在节点中我有
module.exports = myClass;
module.exports.myFunc = myFunc;
可以这样做吗?还是皱眉?有什么缺点,如果有的话?
编辑:我不是在问如何有一个静态方法,我是在问为什么会发生这种情况。
在 JavaScript 中,函数是一个实际值。按数据类型分类的值(数据类型描述一组可能的值)。JavaScript 具有以下数据类型:
- 布尔
- 数
- 字符串
- 定义
- 零
- 象征
- 对象
一个函数显然不是前 6 个函数,它确实是一个对象。因此,它可以具有任意属性,就像任何其他对象一样。
是什么让函数对象与众不同?
每个规范对象都有"内部方法"。您可以将它们视为与普通属性一样,只是它们无法在用户代码中访问。只有 JavaScript 引擎可以访问它们。
函数对象具有一个名为[[Call]]
的内部方法和一个名为[[ECMAScriptCode]]
的内部槽。后者包含函数体的解析表示,并在调用[[Call]]
时进行评估(这发生在调用表达式 (foo()
)中)。
特别是对于类,或者更确切地说是通过class
语法创建的函数,还有内部[[Construct]]
方法。它的工作原理与[[Call]]
非常相似,但在通过new
关键字调用函数时使用。
参见
javascript- 函数和javascript对象之间的主要核心区别是什么?
- 如果函数是对象,那么函数的主体去哪儿了?(参考规范的早期版本)
- 为什么 ES6 类的定义方法中没有属性"原型">
您可以使用static
方法:
class myClass
{
constructor()
{
this.x = 0;
}
static myFunc(){
return 'Hello';
}
}
module.exports = myClass
或者简单地导出myClass
的新实例:
class myClass
{
constructor()
{
this.x = 0;
}
myFunc(){
return 'Hello';
}
}
module.exports = new myClass
在这两种方法中,您都可以将myFunc
视为静态函数:
const myclass = require('myClass');
myClass.myFunc();
// will print out 'Hello'