Написание библиотеки Javascript, удобной для завершения кода и проверки кода - PullRequest
3 голосов
/ 02 апреля 2010

Я недавно создал свою собственную библиотеку 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 жалуется и предупреждает, что не отправляется правильное количество параметров. Как мне это обработать?

EDIT

Я начинаю задумываться, не является ли это проблемой Idea9, потому что у jQuery такая же проблема. У меня, похоже, нет этой проблемы в других проектах.

Ответы [ 5 ]

3 голосов
/ 02 апреля 2010

Я использую IDEA с шаблоном модуля Yahoo, и автозаполнение работает. Google для шаблона модуля 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 там невидимы, потому что они являются «частными».

Для меня этот уровень автозаполнения вполне подходит.

1 голос
/ 06 августа 2010

Это ответ на комментарии к сообщению mwilcox .

Этот пример действительно сработает. Поскольку 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 (или ctags с vim) видеть ваш API, одновременно предотвращая загрязнение глобального пространства имен.

1 голос
/ 02 апреля 2010

Я думаю, будет замечательно, если вы прочитаете что-нибудь о Дугласе Крокфорде. Он является архитектором в рамках 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. зачем изобретать велосипед?

0 голосов
/ 02 апреля 2010

Я пишу свои библиотеки так:

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

new MyLibrary();

Таким образом, в Geany (которая использует CTAGS) MyLibrary хорошо распознается (по большей части, например, memberVar распознается как функция), и кажется, что автозаполнение работает. Я не знаю насчет IDEA9, но вы можете попробовать это таким образом (у меня есть догадка, что он немного более развит, чем CTAGS).

0 голосов
/ 02 апреля 2010

Я рекомендую не использовать частные переменные, но я понимаю, что вы хотите, чтобы они были скрыты от 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/

...