2011-10-07 134 views
10

我希望通过将其分割成不同的文件,并为每个文件提供一个'sub'命名空间。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 a fterwards。

我有很多问题。

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

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

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

  4. 在我的HTML文件中,在我的document.ready函数(jQuery的),我应该初始化前变量或可我首先要

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

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

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

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

如果你通读了这一切,你已经得到了赞赏,欢呼声。

+0

你最好给你的'typeof'比较加引号,并删除'!ex':'if(typeof ex ==“undefined”)''。 –

+0

@Rob W不要一些浏览器返回为空,而不是'undefined'?雅虎名称间隔代码使用!ex – Michael

+0

当一个变量以前从未定义过时,'typeof'将返回'“undefined”'。但是,某些属性在执行检查时可以返回null('typeof null ===“object”')。 –

回答

5

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从VAR前=前有什么不同声明|| {};哪个更好?

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

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

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

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

+0

感谢您的真棒回复。我有几个跟进问题。对于'if(typeof ex =='undefined')'语句,我听说有些浏览器将未定义的变量作为'undefined'返回,但其他浏览器将其返回为null,这就是为什么它有2个部分。
随着代码样式标准,我更多地讨论了函数的命名等,但我对这个使用助手函数扩展的深层对象感兴趣。你能详细说明一下吗?是不是像jQuery.extend?你会认为使用它为每个添加额外的js文件而不是不同的命名空间吗? – Michael

+0

@Michael 1)我从来没有遇到一个浏览器,它赋予一个未定义的变量为null。不过,我在JavaScript中相当新颖。虽然,我认为你已经阅读过关于NULL被视为一个对象,这是另一回事。如果你能给我一个参考,我会很乐意阅读它。 2)是的,它就像jQuery.extend。我认为这一切都归结于项目的规模。如果你有一个小项目,你可以手动添加命名空间,就像你一样。如果这是一个大项目,则需要某种帮助器来扩展名称空间。 – Shef

+0

我认为你是对的,我必须与别的东西混淆。 – Michael

0

对于问题1和3:

在ex.js的闭合样式defenition将允许那些公共功能和VAR /暴露。

我的想法是,最好从anomyous函数返回“ex”与我们需要暴露的函数和变量。

for Q3。在返回函数中定义和使用的那些(私有)变量仍然可用于该函数,并且可以通过公开函数(闭包的属性)使用。

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

你让我想:)当我进一步挖掘到这一点时,将更新帖子。非常好的问题。 :)

2

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

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

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

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

3.我想你是指这个私人方法。

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

在上面的例子中,只有前者可以访问foo。

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

里面的一切作为DOM被加载之前的页面内容被加载

+0

@ 2需要传递什么参数? @ 3如何访问私有功能? @ 4我不明白你的意思 – Michael