【问题标题】:Javascript NamespacingJavascript 命名空间
【发布时间】: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。

我有很多问题。

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

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

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

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

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

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

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

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

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

【问题讨论】:

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

标签: javascript jquery inheritance module namespaces


【解决方案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 = ....}
    猜你喜欢
    • 2010-12-05
    • 2011-03-25
    • 1970-01-01
    • 2011-01-31
    • 2013-03-10
    • 2011-12-05
    • 2015-11-15
    • 2013-09-12
    相关资源
    最近更新 更多