我最近创建了自己的Javascript库,最初使用了以下模式:
var myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
这个问题是我无法真正使用代码完成,因为IDE不知道函数文字返回的属性(我顺便使用IntelliJ IDEA 9)。
我查看了jQuery代码并试图这样做:
(function(window, undefined) {
var myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
window.myLibrary = myLibrary;
}(window));
我尝试了这个,但现在我有一个不同的问题。 IDE也没有真正接受myLibrary
。
我现在解决问题的方式是这样的:
var myLibrary = {
func: function() { },
func2: function() { },
prop: ""
};
myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
但这看起来有点笨拙,我无法弄清楚jQuery是如何做到的。我的另一个问题是如何处理具有任意数量参数的函数。
例如,jQuery.bind
可以使用2个或3个参数,IDE似乎没有抱怨。我试图用我的库做同样的事情,其中一个函数可以带0个参数或1个参数。但是,IDE会抱怨并警告没有发送正确数量的参数。如何处理?
修改
我开始怀疑这是否是一个Idea9问题,因为jQuery有同样的问题。我在其他项目中似乎没有这个问题。
答案 0 :(得分:3)
我正在使用IDEA和雅虎模块模式,我的自动完成工作。谷歌的雅虎模块模式。
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
http://ajaxian.com/archives/a-javascript-module-pattern
TEST = function() {
var SOME_CONSTANT='asd';
function privateStuff(){
var a = 'asd';
return a;
}
return{
someArray:[],
someMethod: function(foo, bar){
var foo = *1
}
,
myProperty:'test'
}
}();
TEST.*2
* 1和* 2我标记了我尝试自动完成的地方。
在* 1中我得到SOME_CONSTANT和privateStuff方法,如果我把它。(自动完成)我可以访问return {}块中的所有方法和属性
当我在* 2上尝试自动完成时,我获得了返回{}块内的所有方法和属性。 SOME_CONSTANT和privateStuff方法在那里是不可见的,因为它们是“私有的”。
对我来说,自动完成程度非常好。
答案 1 :(得分:1)
如果你读到有关道格拉斯·克罗克福德的话,我认为会很棒。他是yahou YUI框架的架构师。之后,您可以更好地了解如何构建一个优秀的框架。对于参数,有2个选项。 1.-通过对象示例发送
{ option :{ var1 : "value" , var2:"value"}, var3 : "value" }
您可以检查选项是否存在。
第二个不太好的是检查参数是否未定义。
function foo(var1,var2){
var var1_this = null;
if(var1 != undefined)
var1_this = var1;
}
只是一个评论为什么要构建一个新的JavaScript框架?使用Prototype,JQuery,Mootols,YUI。为什么重新发明轮子?
答案 2 :(得分:1)
这是对mwilcox's post的评论的回复。
这个例子实际上会起作用。由于myLibrary
的定义没有var
,因此它会自动放入全局命名空间并可以这样访问。通过自执行函数创建的闭包,仍可以在myLibrary
方法中访问私有变量和方法。您可以通过将其放入Firebug或Rhino来轻松尝试。
现在,我不倾向于隐藏我的变量,即我使用Pseudoclassical模式或Prototypal模式,并使用_
预期的私有方法作为前缀:
// Pseudoclassical pattern
function Hello() {}
Hello.prototype = {
method1: function() {},
method2: function() {},
_pseudeoPrivate: function() {}
};
/* Prototypal pattern. To create multiple instances of this object,
you need a helper function such as
function beget(o) {
var F = function() {};
F.prototype = o;
return new F;
}
var instance = beget(world);
*/
var world = {
method1: function() {},
method2: function() {}
};
为了防止我的代码污染全局命名空间,我有一个构建过程,它将我的模块封装在一个闭包中,并将公共api导出到命名空间。 jQuery也使用这种技术。您可以在Github的源代码中查看(请参阅intro.js和outro.js)。
这将允许您使用允许IDE(或带有vim的ctags)的模式来查看您的api,同时还可以防止全局命名空间的污染。
答案 3 :(得分:0)
我建议您不要使用私有变量,但我知道您希望它们隐藏在intellisense中。我就是这样做的:
(function(){
var privateVar = "shhhh!";
var privateMethod = function(){}
myLibray = {
prop:42,
foo: function(){
return privateMethod()
},
bar: function(){
return privateVar;
}
}
})();
通过这种方式,您可以将您的私人资料放入关闭状态,并且您的资料库应该可以访问。
[编辑。我笨拙地没有在匿名函数中包含myLibrary,也看不到私有变量。哎呀。 ]
顺便说一句,我私有变量的原因很糟糕:http://clubajax.org/javascript-private-variables-are-evil/
答案 4 :(得分:0)
我像这样编写我的库:
function MyLibrary() {
// code
}
MyLibrary.prototype.memberFunc = function() {
// code
}
MyLibrary.prototype.memberVar = 5;
new MyLibrary();
这样,在Geany(使用CTAGS)中MyLibrary
被公认(例如,大多数情况下,memberVar被识别为函数)并且自动完成似乎有效。我不知道IDEA9,但你可以这样试试(我预感它比CTAGS更进化)。