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 命名空间的主要内容,如果未能解决你的问题,请参考以下文章