【问题标题】:Javascript utility function to safely create a namespace用于安全创建命名空间的 Javascript 实用程序函数
【发布时间】:2026-01-11 05:25:02
【问题描述】:

在 JS 中动态且安全地创建命名空间的最佳且最安全的方法是什么?

我需要一个用于我目前正在开发的小型实用程序库的实用程序函数。基本上,我希望它检查我的命名空间的任何部分是否已经存在,并且是一个对象,否则这部分必须被初始化并附加为一个空对象。在这里找到它作为 jsbin,以便您可以轻松地摆弄它:

http://jsbin.com/leyijojozo/1/edit?js,console

var createNamespace = function (className) {
    var parts = className.split(".");

    var context = window;

    for (var i = 0; i < parts.length; i++) {
        if (!context[parts[i]] || !context[parts[i]] instanceof Object) {
            context[parts[i]] = {};
        }
        context = context[parts[i]];
    }
    return context;
}

这对于以前不存在命名空间的任何部分的命名空间来说效果很好:

createNamespace("A.B.C");
> {}

返回{}(应该这样做),如果我之后检查控制台,则命名空间完全存在。

但是,如果命名空间的任何部分已经存在,那么函数当然不应该改变它。只要所有现有部分都是对象,它就可以工作;但可能存在命名空间的一个或几个部分,例如简单字符串、数组、布尔值等。

编辑:产生这个问题的实际用例是我有一个网站大量使用。我的应用程序中的一个典型组件定义是这样开始的:

Util.Object.createNamespace("ViewModels.Section.Role").Edit = function (params) { ... }

在许多其他实用程序功能(例如位于 Util.UrlUtil.Cookie 等)中,我已经“命名空间”了我的实用程序库,正如您在此处看到的那样,我喜欢这种方法。

我当然知道我可以简单地手动创建命名空间的每个部分,但作为实用函数爱好者( 任何人?:))我想要一个简单的函数,它以故障安全的方式为我完成。

【问题讨论】:

  • 我个人不会费心在 JavaScript 中创建类似 Java 或 Python 的命名空间,但不久前我登陆了这个库,它可能会做你想做的事。 github.com/mckoss/namespace 或者看看RequireJS requirejs.org
  • 虽然两者看起来很有希望,但也感觉就像在车轮上折断了一只蝴蝶。我对我建议的那种小型实用功能完全满意,但它需要具备故障保护功能。

标签: knockout.js knockout-components underscore javascript namespaces


【解决方案1】:

更保守的方法是创建命名空间if (context[parts[i]] === undefined) 的一部分。那么现存的任何东西都不能被覆盖,如果你试图通过一个非对象(如布尔值)来推送一个命名空间,你最终会出错。

【讨论】:

  • 您能否更明确地解释您的建议涵盖了!context[parts[i]] 未涵盖的哪些情况?
  • 例如,false''0 都将评估为 !context[parts[i]] === true 并被替换为 {}null 也是如此,所以你必须在那里选择你想要的行为。这些都不是instanceof Object。我过去曾使用=== undefined 来处理这种情况,效果令人满意。