编写一个代码完成和代码检查友好的Javascript库

时间:2010-04-01 22:15:31

标签: javascript javascript-framework code-completion code-inspection

我最近创建了自己的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有同样的问题。我在其他项目中似乎没有这个问题。

5 个答案:

答案 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更进化)。