简体   繁体   English

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

[英]Writing a Javascript library that is code-completion and code-inspection friendly

I recently made my own Javascript library and I initially used the following pattern: 我最近创建了自己的Javascript库,我最初使用以下模式:

var myLibrary = (function () {

  var someProp = "...";

  function someFunc() {
    ...
  }

  function someFunc2() {
    ...
  }

  return {
     func: someFunc,
     fun2: someFunc2,
     prop: someProp;
  }

}());

The problem with this is that I can't really use code completion because the IDE doesn't know about the properties that the function literal is returning (I'm using IntelliJ IDEA 9 by the way). 这个问题是我不能真正使用代码完成,因为IDE不知道函数文字返回的属性(我顺便使用IntelliJ IDEA 9)。

I've looked at jQuery code and tried to do this: 我查看了jQuery代码并试图这样做:

(function(window, undefined) {
    var myLibrary = (function () {

      var someProp = "...";

      function someFunc() {
        ...
      }

      function someFunc2() {
        ...
      }

      return {
         func: someFunc,
         fun2: someFunc2,
         prop: someProp;
      }

    }());

    window.myLibrary = myLibrary;
}(window));

I tried this, but now I have a different problem. 我尝试过这个,但现在我有一个不同的问题。 The IDE doesn't really pick up on myLibrary either. IDE也没有真正接受myLibrary

The way I'm solving the problem now is this way: 我现在解决问题的方式是这样的:

var myLibrary = {
   func: function() { },
   func2: function() { },
   prop: ""
};

myLibrary = (function () {

  var someProp = "...";

  function someFunc() {
    ...
  }

  function someFunc2() {
    ...
  }

  return {
     func: someFunc,
     fun2: someFunc2,
     prop: someProp;
  }

}());

But that seems kinda clunky, and I can't exactly figure out how jQuery is doing it. 但这似乎有点笨重,我无法弄清楚jQuery是如何做到的。 Another question I have is how to handle functions with arbitrary numbers of parameters. 我的另一个问题是如何使用任意数量的参数处理函数。

For example, jQuery.bind can take 2 or 3 parameters, and the IDE doesn't seem to complain. 例如, jQuery.bind可以采用2或3个参数,IDE似乎没有抱怨。 I tried to do the same thing with my library, where a function could take 0 arguments or 1 argument. 我试图用我的库做同样的事情,其中​​一个函数可以带0个参数或1个参数。 However, the IDE complains and warns that the correct number of parameters aren't being sent in. How do I handle this? 但是,IDE会抱怨并警告没有发送正确数量的参数。如何处理?

EDIT 编辑

I'm starting to wonder if this is an Idea9 issue because jQuery has the same problem. 我开始怀疑这是否是一个Idea9问题,因为jQuery有同样的问题。 I don't seem to have this problem in other projects though. 我似乎在其他项目中没有这个问题。

I'm using IDEA with yahoo module pattern and my autocomplete works. 我正在使用IDEA与雅虎模块模式和我的自动完成功能。 Google for yahoo module pattern. 谷歌为雅虎模块模式。

http://www.yuiblog.com/blog/2007/06/12/module-pattern/ http://www.yuiblog.com/blog/2007/06/12/module-pattern/

http://ajaxian.com/archives/a-javascript-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

with *1 and *2 i marked places where i tried auto complete. 与* 1和* 2我标记我尝试自动完成的地方。

in *1 i get SOME_CONSTANT and privateStuff method, and if i put this.(autocomplete) i get access to all the methods and properties inside of return {} block 在* 1我得到SOME_CONSTANT和privateStuff方法,如果我把它。(自动完成)我可以访问return {}块内的所有方法和属性

when i try autocomplete on *2 i get all the methods and properties inside return {} block. 当我在* 2上尝试自动完成时,我获得了返回{}块内的所有方法和属性。 SOME_CONSTANT and privateStuff method are invisibile there, because they are "private". SOME_CONSTANT和privateStuff方法在那里是不可见的,因为它们是“私有的”。

For me that level of autocomplete is quite fine. 对我来说,自动完成程度非常好。

I think will be great if you read something about Douglas Crockford. 如果你读一些关于道格拉斯·克罗克福德的话,我想会很棒。 He is THE architect in yahou YUI framework. 他是yahou YUI框架的架构师。 And after that you can have a better idea to how build a great framework. 之后,您可以更好地了解如何构建一个优秀的框架。 And for the parameter there are 2 options. 对于参数,有2个选项。 1.- send via object example 1.-通过对象示例发送

{ option :{ var1 : "value" , var2:"value"}, var3 : "value" }

And the you can check if the option exist. 您可以检查选项是否存在。

The second one not to great is check if the parameter is undefined. 第二个不太好的是检查参数是否未定义。

function foo(var1,var2){
   var var1_this = null;
     if(var1 != undefined)
      var1_this = var1;
}

and just a comment why build a new javascript framework? 并只是一个评论为什么要构建一个新的JavaScript框架? use Prototype, JQuery, Mootols, YUI. 使用Prototype,JQuery,Mootols,YUI。 why reinventing the wheel? 为什么重新发明轮子?

This is in reply to the comments to mwilcox's post . 这是对mwilcox帖子的评论的回复。

That example will actually work. 这个例子实际上会起作用。 Since myLibrary is defined without var , it is automatically put into the global namespace and accessible as such. 由于myLibrary是在没有var情况下定义的,因此它会自动放入全局命名空间并可以这样访问。 Through the closure created by the self-executing function, the private variables and methods are still accessible in the myLibrary methods. 通过自执行函数创建的闭包,私有变量和方法仍可在myLibrary方法中访问。 You can easily try this out by putting it into Firebug or Rhino. 您可以通过将其放入Firebug或Rhino来轻松尝试。

These days, I do not tend to hide my variables, ie I use the Pseudoclassical pattern or the Prototypal pattern and prefix my intended private methods with an _ : 这些天,我不倾向于隐藏我的变量,即我使用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() {}
};

To prevent my code from polluting the global namespace, I have a build process that wraps my modules in a closure and exports the public api to the namespace. 为了防止我的代码污染全局命名空间,我有一个构建过程,它将我的模块封装在一个闭包中,并将公共api导出到命名空间。 This technique is also used by jQuery. jQuery也使用这种技术。 You can see that in their source code (look at intro.js & outro.js) on Github . 您可以在Github上看到它们的源代码(查看intro.js和outro.js)。

This would allow you to use a pattern that allows your IDE (or ctags with vim) to see your api, whilst also preventing the pollution of the global namespace. 这将允许您使用允许IDE(或带有vim的ctags)的模式来查看您的api,同时还可以防止全局命名空间的污染。

I recommend that you don't use private variables, but I understand you want them hidden from the intellisense. 我建议你不要使用私有变量,但我知道你希望它们隐藏在intellisense中。 This is how I would do it: 我就是这样做的:

(function(){
    var privateVar = "shhhh!";
    var privateMethod = function(){}


    myLibray = {
        prop:42,
        foo: function(){
            return privateMethod()
        },
        bar: function(){
            return privateVar;
        }
    }

})();

This way you can have your private stuff in a closure and your library should be accessible. 通过这种方式,您可以将您的私有内容放入闭包中,并且您的库可以访问。

[ edited. [编辑。 I clumsily did not include myLibrary in the anonymous function and it could not see the private vars. 我笨拙地没有在匿名函数中包含myLibrary,也看不到私有变量。 oops. 哎呀。 ] ]

BTW, my reasons for private variables being bad: http://clubajax.org/javascript-private-variables-are-evil/ BTW,我私有变量的原因很糟糕: http//clubajax.org/javascript-private-variables-are-evil/

I write my libraries like this: 我像这样编写我的库:

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

new MyLibrary();

This way, in Geany (which uses CTAGS) MyLibrary is well recognized (for the most part, for example, memberVar is recognized as a function) and autocompletion seems to work. 这样,在Geany(使用CTAGS)中, MyLibrary被很好地识别(例如,大多数情况下,memberVar被识别为函数)并且自动完成似乎有效。 I don't know about IDEA9, but you could try it this way (I have a hunch it's a bit more evolved than CTAGS). 我不知道IDEA9,但你可以这样尝试(我有预感它比CTAGS更进化)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM