typescript—第七天,命名空间

本文探讨了在没有命名空间时全局变量带来的问题,并详细介绍了TypeScript中的命名空间使用,如何实现组件化,以及如何将多文件编译成一个文件。通过命名空间,可以减少全局变量,实现模块化封装,防止变量污染。此外,还提到了子命名空间的概念,进一步增强了代码组织能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

没有命名空间时的问题

先写一下这样代码,用类的形式在index.html中实现header,content和Footer部分,类似我们常说的模板。

在page.ts文件里,写出下面的代码:

class Header {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Header";
    document.body.appendChild(elem);
  }
}

class Content {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Content";
    document.body.appendChild(elem);
  }
}

class Footer {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Footer";
    document.body.appendChild(elem);
  }
}

class Page {
  constructor() {
    new Header();
    new Content();
    new Footer();
  }
}

写完后我们用tsc进行编译一次,然后修改index.html文件,在标签里引入

<body>
  <script>new Page();</script>
</body>

这时候再到浏览器进行预览,就可以看到对应的页面被展现出来了。看起来没有什么问题,但是有经验的程序员就会发现,这样写全部都是全局变量(通过查看./build/page.js文件可以看出全部都是var声明的变量)。过多的全局变量会让我们代码变的不可维护。

这时候你在浏览器的控制台(Console)中,分别输入Header、Content、Footer和Page都时可以拿到对应的变量的,说明他们全都是全局变量。

其实你理想的是,只要有Page这个全局变量就足够了,剩下的可以模块化封装起来,不暴露到全局。

命名空间的使用

命名空间这个语法,很类似编程中常说的模块化思想,比如webpack打包时,每个模块有自己的环境,不会污染其他模块,不会有全局变量产生。命名空间就跟这个很类似,注意这里是类似,而不是相同。

命名空间声明的关键词是namespace 比如声明一个namespace Home,需要暴露出去的类,可以使用export关键词,这样只有暴漏出去的类是全局的,其他的不会再生成全局污染了。修改后的代码如下:

namespace Home {
  class Header {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Header";
      document.body.appendChild(elem);
    }
  }

  class Content {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Content";
      document.body.appendChild(elem);
    }
  }

  class Footer {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Footer";
      document.body.appendChild(elem);
    }
  }

  export class Page {
    constructor() {
      new Header();
      new Content();
      new Footer();
    }
  }
}

TS 代码写完后,再到index.html文件中进行修改,用命名空间的形式进行调用,就可以正常了。 写完后,记得用tsc编译一下,当然你也可以使用tsc -w进行监视了,只要有改变就会进行重新编译。

new Home.Page();

现在再到浏览器中进行查看,可以看到现在就只有Home.Page是在控制台可以得到的,其他的Home.Header…这些都是得不到的,说明只有Home.Page是全局的,其他的都是模块化私有的。

这就是 TypeScript 给我们提供的类似模块化开发的语法,它的好处就是让全局变量减少了很多,实现了基本的封装,减少了全局变量的污染。

用命名空间实现组件化

上面的代码虽实现了模块化和全局变量的污染,但是我们工作中分的要更细致一些,会单独写一个components的文件,然后进行组件化。

在src目录下新建一个文件components.ts,编写代码如下:

namespace Components {
  export class Header {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Header";
      document.body.appendChild(elem);
    }
  }

  export class Content {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Content";
      document.body.appendChild(elem);
    }
  }

  export class Footer {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Footer";
      document.body.appendChild(elem);
    }
  }
}

这里需要注意的是,我每个类(class)都使用了export导出,导出后就可以在page.ts中使用这些组件了。比如这样使用-代码如下。

namespace Home {
  export class Page {
    constructor() {
      new Components.Header();
      new Components.Content();
      new Components.Footer();
    }
  }
}

这时候你可以使用tsc进行重新编译,但在预览时,你会发现还是会报错,找不到Components,想解决这个问题,我们必须要在index.html里进行引入components.js文件。

<script src="./build/page.js"></script>
<script src="./build/components.js"></script>

这样才可以正常的出现效果。但这样引入太麻烦了,可不可以像webpack一样,只生成一个文件那?那答案是肯定的。

多文件编译成一个文件

直接打开tsconfig.json文件,然后找到outFile配置项,这个就是用来生成一个文件的设置,但是如果设置了它,就不再支持"module":"commonjs"设置了,我们需要把它改成"module":"amd",然后在去掉对应的outFile注释,设置成下面的样子。

{
  "outFile": "./build/page.js"
}

配置好后,删除掉build下的js文件,然后用tsc进行再次编译。

然后删掉index.html文件中的component.js,在浏览器里还是可以正常运行的。

子命名空间

也就是说在命名空间里,再写一个命名空间,比如在Components.ts文件下修改代码如下。

namespace Components {
  export namespace SubComponents {
    export class Test {}
  }

  //someting ...
}

写完后在控制台再次编辑tsc,然后你在浏览器中也是可以查到这个命名空间的Components.SubComponents.Test(需要刷新页面后才会显示)。
学习视频
https://www.bilibili.com/video/BV1qV41167VD?p=22
学习资料
https://jspang.com/detailed?id=63#toc377

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值