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

Posted

技术标签:

【中文标题】编写代码完成和代码检查友好的 Javascript 库【英文标题】:Writing a Javascript library that is code-completion and code-inspection friendly 【发布时间】:2011-02-03 13:49:31 【问题描述】:

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

【问题讨论】:

我知道,对吧?我们都应该在汇编中编码!搞砸一切! 我确定这是他的个人图书馆。 它实际上是一个验证框架,它采用了不同的方法——通过自定义属性进行注释(在 html5 中有效)。实验和概念验证。 【参考方案1】:

我正在使用带有 yahoo 模块模式的 IDEA,并且我的自动完成功能正常工作。 Google for yahoo 模块模式。

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 上尝试自动完成时,我得到了 return 块内的所有方法和属性。 SOME_CONSTANT 和 privateStuff 方法在那里是不可见的,因为它们是“私有的”。

对我来说,这种级别的自动完成非常好。

【讨论】:

我真的没有看到他的返回 块:)。我编辑了我的答案。 不能解决我的问题(这可能是一个想法问题),但它通常可以回答我的问题! :)【参考方案2】:

如果你能读到一些关于 Douglas Crockford 的文章,我觉得会很棒。他是 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 框架?使用原型,JQuery,Mootols,YUI。为什么要重新发明***?

【讨论】:

大概学习了。那就是重新发明***没问题的时候。 也不要忘记你的应用程序应该只使用 Prototype、jQ 和一些底层的东西,如果你正在编写新的,比如说可视化框架,你应该使用 Prototype 作为你的基础框架,并且所有的图表和东西应该在另一个建立在 Prototype、jQ 等之上的 FW 中...... 是的,就 jQuery 或 Prototype 而言,我并不想重新发明***。我正在研究一个验证框架。【参考方案3】:

这是对mwilcox's post的cmets的回复。

这个例子确实有效。由于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 也使用了这种技术。您可以在 Github 上的源代码(查看 intro.js 和 outro.js)中看到这一点。

这将允许您使用允许您的 IDE(或带有 vim 的 ctags)查看您的 api 的模式,同时还可以防止全局命名空间的污染。

【讨论】:

【参考方案4】:

我这样写我的库:

function MyLibrary() 
    // code

MyLibrary.prototype.memberFunc = function() 
    // code

MyLibrary.prototype.memberVar = 5;

new MyLibrary();

这样,在 Geany(使用 CTAGS)中,MyLibrary 被很好地识别(例如,在大多数情况下,memberVar 被识别为函数)并且自动完成似乎工作。我不知道 IDEA9,但你可以这样尝试(我预感它比 CTAGS 进化了一点)。

【讨论】:

我也见过这种模式。与单例模式相比,这种方法有什么优势吗? 能够使用同一个对象的多个实例吗? :) 此外,IMO 代码的可读性更高。 当然 :) 我想知道在这种情况下拥有多个实例对我来说是否有意义!我会继续努力弄清楚发生了什么。【参考方案5】:

我建议您不要使用私有变量,但我知道您希望它们对智能感知隐藏。我会这样做:

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

【讨论】:

这行得通吗?之后闭包中的本地变量不会超出范围吗? 我不确定这将如何工作。 privateVarprivateMethod 将无法被 myLibrary 访问,不是吗? 这行不通。 privateVarprivateMethod 将在他们自己的小世界里;没有任何东西可以访问它们。

以上是关于编写代码完成和代码检查友好的 Javascript 库的主要内容,如果未能解决你的问题,请参考以下文章

grunt -- javascript自动化工具

NodeJS - 等到流式传输多个文件完成后再继续编写代码

gulp

gulp

如何使用javascript创建不自动完成的搜索来检查json文件中是不是存在内容

XSS 和友好的 URL