JavaScript设计模式(1)——组织函数

19 阅读3分钟

前言

一个页面如果有很强的交互逻辑,可能就有很多方法(函数),假如方法只是简单的罗列在全局环境下,如果是个人开发且方法不多的情况下,开发者记得方法名不容易产生同名方法。可是一旦方法多或者多人协同开发或者在过了很长时间后维护时,就很容易发生方法同名,那么下面的方法可能会覆盖上层的方法,导致BUG。 javascript是一种很灵活的语言,在组织方法时有多种方式。

使用let或const声明函数

如果确实项目比较小且个人开发,就是想在全局罗列方法,那么建议使用let或const声明函数

let a = function () {};
const a = function () {};

当有同名方法出现时,会报错提示

image.png

如果用function来使用,我们看看效果

function a() {
  console.log("a");
}
function a() {
  console.log("A");
}

a();

image.png

可以看到下方的a方法覆盖了上方的。

虽然可行,但还是建议方法放在一个容器中,如果后续要扩展项目,那么好管理也方便复用。

使用对象与函数作为方法的容器

对象

 const foo={
     a:function(){}
     b:function(){}
 }
 foo.a()
 foo.b()

使用一个简单的对象来封装方法。

函数

 const foo=function(){}
 foo.a=function(){}
 foo.b=function(){}

函数也是对象,函数通过原型链能拿到Function.prototype的方法,像call,apply等等。把函数当作对象来封装方法。

用函数调用封装方法

 const foo=function(){
     return {
         a:function(){},
         b:function(){}
     }
 }
 const bar= foo()
 bar.a()
 bar.b()

但是呢更多时候是在立即执行函数中使用,也就是俗称iife。

const foo = (function () {
  return {
    a: function () {
      console.log("aaa");
    },
    b: function () {},
  };
})();

// 使用解构语法,解构出方法
const { a } = foo;
a();

然后我们看一下vue中reactivity模块中怎么使用的 npm i vue

image.png

这个global就表示可以通过<script src=""><script/>来使用,其方式就是iife

image.png

这里多了一个参数exports,它就是传进来的{}。

image.png

image.png

然后在对象exports中挂载众多方法,最后将export导出。

那其实和上面写的直接return一个对象差不多效果。

用类的形式来组织

方法1:方法挂载在this上

const foo=function(){
     this.a=function(){
     // return this,就返回当前的实例,即实现链式调用
         return this
     }
     this.b=function(){
         return this
     }
 }
 const foo1=new foo()
 // 链式调用
 foo1.a().b()

方法挂载在this上这种方式不推荐,因为每次new一个实例,实例上就会有这些方法。内存开销大

方法2:方法挂载在构造函数的原型上

 const foo=function(){}
    foo.prototype.a=function(){}
     foo.prototype.b=function(){}

方法挂载在构造函数的原型上,new的实例,都会通过原型链找到方法。内存开销小。

如果觉得方法太多赋值为对象,不要忘记prototype中包含constructor属性

 const foo=function(){}
    foo.prototype.a=function(){}
     foo.prototype.b=function(){}
     foo.prototype={
          constructor:foo
          a:function(){},
          b:function(){}
     }

constructor属性是指回foo构造函数的

还可以通过Function.prototype做文章来添加方法,本质上也是利用了原型链

 Function.prototype.addMethod=function(name,fn){
    this.prototype[name]=fn
    return this
}

const a=function(){}
a.addMethod('aaa',fn)

那么在a函数的prototype上fn可以调用了。

当然如果a函数上如果也有一个方法addMethod,就会覆盖Function.prototype.addMethod方法。

小结

介绍了几种组织函数的方式

  • 使用let或const声明函数
  • 使用对象与函数作为方法的容器
  • 用函数调用封装方法
  • 用类的形式来组织

具体使用哪种方式要结合实际需求来使用。