编写一个支持代码补全和代码检查的JavaScript库

3

我最近做了一个自己的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似乎没有抱怨。我尝试在我的库中做同样的事情,其中一个函数可以不带参数或带一个参数。然而,IDE会抱怨并警告说没有发送正确数量的参数。我该如何处理这个问题?

编辑

我开始怀疑这可能是Idea9的问题,因为jQuery也有同样的问题。不过,在其他项目中我好像没有这个问题。


2
我知道,对吧?我们都应该用汇编语言编程!其他的都可以滚蛋! - Vivin Paliath
我确定这是他的个人代码库。 - mwilcox
这实际上是一个采用不同方法的验证框架 - 通过自定义属性的注释(在HTML5中有效)。实验性和概念验证。 - Vivin Paliath
5个回答

3

我正在使用带有雅虎模块模式的IDEA,并且我的自动完成功能正常工作。在Google中搜索“雅虎模块模式”。

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 方法,如果我输入 this.(autocomplete),我可以访问返回 {} 块内部的所有方法和属性。

当我在 *2 上尝试自动完成时,我会得到返回 {} 块内的所有方法和属性。SOME_CONSTANT 和 privateStuff 方法在那里是不可见的,因为它们是“私有”的。

对我来说,这种自动完成水平已经足够好了。


我真的没有看到他的return {}块 :). 我编辑了我的答案。 - kodisha
没有解决我的问题(可能是一个想法问题),但它基本上回答了我的问题! :) - Vivin Paliath

1

这是回复mwilcox's post的评论。

那个例子实际上可以工作。由于myLibrary没有使用var定义,它会自动放入全局命名空间并作为此类可访问。通过自执行函数创建的闭包,私有变量和方法仍然可以在myLibrary方法中访问。您可以将其放入Firebug或Rhino中轻松尝试。

现在,我不倾向于隐藏我的变量,即我使用伪类模式或原型模式,并在_前缀下使用我的预期私有方法:

// 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使用。您可以在他们的源代码(查看intro.js和outro.js)上看到这一点,链接在Github上。
这将允许您使用一种模式,使您的IDE(或带vim的ctags)能够查看您的API,同时还防止了全局命名空间的污染。

1

我认为如果你读一些关于Douglas Crockford的东西会很棒。他是yahou YUI框架中的主要架构师。在那之后,你可以更好地了解如何构建一个伟大的框架。至于参数,有两个选项。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、Mootools、YUI不好吗?重复造轮子有何意义?


可能是为了学习,这时重新发明轮子就可以了。 - Hugo Estrada
请注意,您的应用程序应仅使用Prototype、jQ等低级别工具。如果您正在编写新的可视化框架,您应该将Prototype作为基础框架,并将所有图表等内容放在另一个建立在Prototype、jQ等之上的框架中。 - kodisha
是的,就jQuery或Prototype而言,我并不想重新发明轮子。我正在开发一个验证框架。 - Vivin Paliath

0

我建议你不要使用私有变量,但我理解你想让它们在智能感知中隐藏起来。我会这样做:

(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/


这个能行吗?闭包中的局部变量不会超出作用域吗? - Zack The Human
我不确定这会怎么样。privateVarprivateMethod对于myLibrary来说是不可访问的,对吗? - Vivin Paliath
这样做不会起作用。privateVarprivateMethod将处于它们自己的小世界中,没有任何东西能够访问它们。 - Matt

0

我会这样编写我的库:

function MyLibrary() {
    // code
}
MyLibrary.prototype.memberFunc = function() {
    // code
}
MyLibrary.prototype.memberVar = 5;

new MyLibrary();

在Geany中(使用CTAGS),MyLibrary被很好地识别(大部分情况下,例如,成员变量被识别为函数),并且智能补全似乎正常工作。我不知道IDEA9是否会这样,但你可以尝试一下这种方法(我有点感觉它比CTAGS更进化)。

我也见过这种模式。相比于单例模式,这种方法有哪些优势? - Vivin Paliath
能够使用同一对象的多个实例? :) 另外,我认为代码更易读。 - Felix
当然 :) 我在想在这种情况下是否有多个实例会有意义!我会继续努力解决问题。 - Vivin Paliath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接