Написание библиотеки Javascript, удобной для завершения и проверки кода.
-
23-09-2019 - |
Вопрос
Недавно я создал свою собственную библиотеку 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 та же проблема.Хотя в других проектах у меня нет этой проблемы.
Решение
Я использую 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 здесь невидимы, поскольку они являются «частными».
Для меня такой уровень автозаполнения вполне устраивает.
Другие советы
Думаю, будет здорово, если вы прочтете что-нибудь о Дугласе Крокфорде.Он архитектор в рамках Yahoo 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.зачем изобретать велосипед?
Это ответ на комментарии к пост Мвилкокса.
Этот пример действительно будет работать.С 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) на Гитхаб.
Это позволит вам использовать шаблон, который позволит вашей IDE (или ctags с vim) видеть ваш API, а также предотвратит загрязнение глобального пространства имен.
Я пишу свои библиотеки следующим образом:
function MyLibrary() {
// code
}
MyLibrary.prototype.memberFunc = function() {
// code
}
MyLibrary.prototype.memberVar = 5;
new MyLibrary();
Таким образом, в Geany (который использует CTAGS) MyLibrary
хорошо распознается (например, по большей частиmemberVar распознается как функция), и автодополнение, похоже, работает.Я не знаю насчет IDEA9, но вы можете попробовать так (у меня есть подозрение, что он немного более развит, чем CTAGS).
Я рекомендую вам не использовать частные переменные, но я понимаю, что вы хотите скрыть их от 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/