Javascript 中的命名空间到底是个什么东西?

《Javascript 中的命名空间到底是个什么东西?》

刚学习 JS 的时候,总是听过一个名词:命名空间。当时对这个东西并不能够很好的理解,命名为什么还会有空间呢?加上空间能有什么用处?

其实在很多编程语言中,都有命名空间这个概念,它们自身就已经具备了很好的文件和包管理机制,通过 import include require 等等命令,能够引入其他的模块、包或者文件,从而避免文件之间的变量命名重复问题。

然而在 JS 中,脚本文件是通过 script 标签引入的,同时由于 JS 的变量和函数声明的特殊性,一不小心就会造成环境污染,将一个变量或者属性暴露在全局,或者被别的文件中的同名变量所覆盖,于是就有了命名空间这样一个概念。

在 js 中,声明变量时加上关键字和不加关键字是不一样的,var arg = 1 这样的声明,arg 的作用域只在当前页面或者当前的方法中;但是如果声明时不加 var 而是直接声明 arg = 1 ,js 就会认为这是一个全局变量,即使它是在一个函数体中声明的。

/* a.js */
var people = 'xiaoming'

/* b.js */
var people = {
    name: 'xiaohong',
    age: 18
}

/* index.html */
<script src="./a.js"></script>
<script src="./b.js"></script>

console.log(people === 'xiaoming') // false

在上面的代码块中,后引入页面的 b.js 文件的 people 变量就覆盖了 a.jspeople 变量

上面这种情况,通过命名空间我们就可以很好地解决:

// 如果在 window 上没有 ns 属性,就将 ns 属性挂载到 window 上,作为根空间存在
if (!window.ns) window.ns = {}

// 当我们需要声明一个新的变量或者方法时,就可以添加到 ns 中,但是如果在 ns 上随意添加,依然会出现覆盖的情况,所以可以以文件为区分单位来添加

/* a.js */
var a = {}
a.people = 'xiaoming'
a.getPeopleName = function () {
    return a.people
}
ns.a = a

/* b.js */
var b = {}
b.people = {
    name: 'xiaohong',
    age: 18
}
ns.b = b

// 在页面上引入上面两个文件后,我们可以通过下面的方式来分开使用两个 people
console.log(ns.a.people)
console.log(ns.b.people)

// 通过上面的方法,也可以实现在已经引入的脚本中调用其他脚本的变量和方法

/* c.js */
// 如果 ns.a 存在,则调用它的 getPeopleName 方法
ns.a && ns.a.getPeopleName()

上面的代码块已经简单的说明了命名空间的书写方式,当然你也可以通过其他方式来确定命名空间的各级空间命名方式,比如根节点就可以模仿其他语言的方式,通过倒写的域名来表示 com.google.www

既然命名空间的主要作用是用来防止变量被覆盖、污染全局环境,那么有没有其他方式来实现这一的作用呢?

最简单的,通过立即执行函数就可以比较好的解决这个问题(前提是变量要用 var const let) 声明:

const moduleA = function () {
    // 私有变量、方法写在函数体中
    const a = 1
    function func1 () {...}

    // 需要暴露出来的方法通过返回一个对象写在 return 中
    return {
      b: 2,
      func2: () => {...}
    }
} ()

moduleA.a // 报错
moduleA.b // 2

或者通过现在普遍使用的 require.js 等第三方库,ES6 支持的 import 语法来实现模块的引入,也可以防止模块之间的变量覆盖等情况出现。

《Javascript 中的命名空间到底是个什么东西?》 扫码关注微信公众号【前端程序员的斜杠青年进化录】
《Javascript 中的命名空间到底是个什么东西?》 微信扫码,给我赞赏一下~

    原文作者:次人君在野原之森网络工作室
    原文地址: https://www.jianshu.com/p/304862d787f4
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞