Javascript 命名空间

Posted

技术标签:

【中文标题】Javascript 命名空间【英文标题】:Javascript Namespacing 【发布时间】:2011-12-02 19:45:13 【问题描述】:

我希望通过将我的 javascript 拆分为不同的文件并为每个文件提供一个像这样的“子”命名空间来使我的 javascript 更加模块化。

subA.js

if(typeof ex == "undefined") 
    var ex = ;


ex.subA = function() 
//all functions of subA here

subB 等也一样

目前我有 1 个文件,ex.js

var ex = (function() 
    //private vars/funcs
    return 
        //public vars/funcs
    
)();

看起来我应该将我的大部分函数移动到 subA.js 和 subB.js,但仍然在开始时包含 ex.js,然后是 subA.js 和 subB.js。

我有很多问题。

    我很难记住我是如何制作初始命名空间文件 ex.js 的。看起来匿名函数最初是为了将所有内容设为私有,但我不记得为什么需要将它括在括号中,然后在末尾使用 (); 立即执行。

    从 q1 开始,我的子文件是否应该与 ex.js 的格式相同,即,将 anon 函数包裹在括号中并立即执行?

    看起来子文件只能访问ex的公共功能,这是真的吗?如果是,我怎样才能让我的子文件也访问私有函数?

    在我的 html 文件中,在我的 document.ready 函数 (jQuery) 中,我应该将 ex 初始化为一个变量,还是可以通过以下方式单独调用每个函数

$(document).ready(function() 
    ex.doSomething();
    ex.doSomethingElse();

这两者有区别吗?我认为当包含 ex.js 时,会立即创建一个全局变量 ex(由于立即执行匿名函数),所以我不需要在 document.ready 中重新定义它。

    subA.js 中的第一个 if 语句与 var ex = ex || ; 有什么不同吗?哪个更好?

    你使用什么 js 代码风格标准?

如果您通读了所有这些内容,那么您已经值得一票了,干杯。

【问题讨论】:

您最好在typeof比较中添加引号,并删除!ex:if(typeof ex == "undefined") @Rob W 某些浏览器不是将 ex 返回为 null 而不是“未定义”吗? yahoo 名称间距代码使用 !ex 当一个变量以前从未定义过时,typeof 将返回"undefined"。但是,某些属性在执行检查时可能会返回 null (typeof null === "object")。 【参考方案1】:

对于问题 1 和 3:

ex.js 中的闭包样式定义将允许这些公共函数和 vars/exposed。

我的想法是,最好从异常函数中返回“ex”以及我们需要公开的函数和变量。

第三季度。在返回函数中定义和使用的那些(私有)变量对于函数仍然可用,并且可以通过暴露的函数(闭包属性)使用。

如果外部脚本包含在文件的部分或顶部,则 ex 应该在 document.ready 之前可用,并且应该立即可用。

你让我思考 :) 在我进一步深入研究时会更新帖子。很好的问题。 :)

【讨论】:

【参考方案2】:

在您的设计中,您将无法访问该 lambda 函数中定义的私有变量/函数,因为它只返回一个对象,或者您想使用 new

1.没有()ex是一个函数而不是函数返回的对象。

2.不需要,除非你想传递一些参数进行初始化。例如

ex.my = (function(name) var my_name = name;)('bar');

3.我想你的意思是这个私有方法。

ex = (function() 
    var foo = 'bar';
    return 
        show: function() alert(foo);
    
)();

在上述情况下,只有 ex 可以访问 foo。

4.不需要,一切准备就绪时调用$(document).ready(),如果你已经加载了ex.js,则初始化完成。

它里面的所有东西都会在 DOM 被加载后和页面内容被加载之前加载

【讨论】:

@2 需要传递哪些参数? @3 我如何访问私有功能? @4 我不明白你的意思【参考方案3】:

1。 function() return 是一个闭包,用于将“隐私”添加到您不希望在该函数范围内的其他任何地方访问的变量和函数。函数(function()) 周围的括号创建了一个函数表达式。使用它们,因为当您尝试立即执行函数 function()() 而不向 () 传递任何参数时,解析器会报错。

2。如果您希望 subA 或任何其他扩展对象拥有自己的子功能,那么是的,您必须这样声明它,但不一定是 clousure。

你可以的

ex.subA = function(x, y)
    return x+y;

可以叫var sum = ex.subA(2, 3);

或者你可以这样做

ex.subA = (function()

    return 
        add: function(x, y)
            return x+y;
        ,
        multiply: function(x, y)
            return x*y;
        
    
)();

那就叫它var sum = ex.subA.add(2, 3); var multiplication = ex.subA.multiply(2,3);

有很多方法可以做到这一点。

3。是的,它是真的。您可以公开私有函数。关闭不允许任何其他方式来做到这一点。

4。如果您想别名,是的,您可以将其分配给变量。但是,没有必要。它会按照您描述的方式正常工作。

阅读 Essential JavaScript Namespacing Patterns 以了解 javascript 命名空间的一些基础知识和模式。


subA.js 中的第一个 if 语句与 var ex = ex || 有什么不同吗? ;哪个更好?

首先,if 语句应该是if(typeof ex == 'undefined')typeof 返回一个字符串。无需检查ex 是否为假。

是的,它是不同的。如果变量ex 已经定义,if 语句将不会进行任何变量赋值。因此,if 语句更好。

你使用什么 js 代码风格标准?

取决于项目的范围,但主要是通过辅助函数扩展的深层对象。

【讨论】:

感谢您的精彩回复。我有几个后续问题。对于if(typeof ex == 'undefined') 语句,我听说有些浏览器将未定义的变量返回为“未定义”,而其他浏览器将其返回为空,这就是它有两部分的原因。 对于代码样式标准,我更多地谈论函数的命名等,但我对这个使用辅助函数扩展的深层对象感兴趣。你能详细说明一下吗?是不是类似于 jQuery.extend?您是否认为使用它来添加额外的 js 文件而不是为每个文件添加不同的命名空间? @Michael 1) 我从未遇到过将 null 分配给未定义变量的浏览器。但是,我在 JavaScript 方面相当陌生。虽然,我认为您已经阅读了有关 NULL 被视为对象的信息,这是另一回事。如果你能给我一个参考,我很乐意阅读它。 2) 是的,它类似于 jQuery.extend。我认为这一切都取决于项目的规模。如果你有一个小项目,你可以手动添加命名空间,就像你一样。如果它是一个大项目,你需要某种帮助来扩展命名空间。 我认为你是对的,我一定是把它和别的东西搞混了。 "那么就和上一个一样调用吧。" - 你在那里描述的方法是不可能的。 由于我的子函数需要 ex 已经存在(因为它们的某些函数使用 ex 函数),我应该使用它来代替。 if(typeof ex == "undefined") window.console.log("ex.js needs to be included before subX"); else ex.subA = ....

以上是关于Javascript 命名空间的主要内容,如果未能解决你的问题,请参考以下文章

“JavaScript 命名空间”是啥意思? [复制]

如何声明对现有命名空间的引用,该命名空间可在运行时从 JavaScript 包中获得

使用 JavaScript 命名空间是不是有任何危险?

Javascript 命名空间

命名空间动态加载的 javascript 文件的内容

javascript 命名空间的首选技术