何时使用静态方法与实例方法

2,091 阅读3分钟

昨天用koa做批量路由导入的时候提取了一个公共方法,但这个方法是一个含有多个静态方法的类,需要导出然后调用,后来我突然想到为何不写成含有constructor构造函数的非静态方法的类,然后在外面new实例一遍就能拿到这个公共调用的方法呢?显然这两者都能达到实现路由判断的效果,但区别在哪里呢?出于性能和应用场景我该选哪个?

从内存性能分析:
在使用静态方法的过程中,因为静态方法是在程序一开始就会加载进内存,这也是为何可以直接在程序中直接调用静态方法的原因,而实例化方法是在程序中调用的时候(new一遍)才会加载进内存,所以可以看到静态方法很快,但是太多会占用内存静态内存是连续的,因为是在程序开始时就生成了,而实例申请的是离散的空间,所以当然没有静态方法快,而且静态内存是有限制的,太多了程序会启动不了。  静态成员属于类所有,非静态成员属于类的实例所有。


从使用场景分析:

若方法经常被调用,则用静态方法更佳,因为这样可以避免频繁地实例化对象导致的资源占用,提高性能。然而,由于静态的东西,在构造的时候是在堆中声称的,在结束之前不会被释放与改变,会一直占用内存空间,所以不宜有过多的静态成员。因此若方法不会经常被调用,则使用实例方法可能会更好。

(堆与栈的区别见如下)

栈(stack)会自动分配内存空间,会自动释放。
基本类型:简单的数据段,存放在栈内存中,占据固定大小的空间。基本数据类型包括Undefined,String,Boolean,Null,Number
堆(heap)动态分配的内存,大小不定也不会自动释放。
引用类型:指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量实际上保存的不是变量本身,指向该对象的指针。
从一个向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终指向同一个对象。即复制的是栈中的地址而不是堆中的对象。
从一个变量复向另一个变量复制基本类型的值,会创建这个值的副本。


从线程并发的角度考虑:
要考虑方法是否存在严重的并发,如果并发的可能性很大,则不适宜使用静态方法。如果并发的可能性很小,或者通过简单的同步操作可以保证线程安全,那就可以考虑使用静态方法,这种情况下,静态方法要更快,更方便。

显然我从应用场景,路由需频繁调且需要反映速度快的角度我会考虑静态方法,但只用于少量静态方法。