Pergunta

Recentemente criei minha própria biblioteca Javascript e inicialmente usei o seguinte padrão:

var myLibrary = (function () {

  var someProp = "...";

  function someFunc() {
    ...
  }

  function someFunc2() {
    ...
  }

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

}());

O problema com isso é que não posso realmente usar o preenchimento de código porque o IDE não conhece as propriedades que a função literal está retornando (a propósito, estou usando o IntelliJ IDEA 9).

Eu olhei o código jQuery e tentei fazer isso:

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

      var someProp = "...";

      function someFunc() {
        ...
      }

      function someFunc2() {
        ...
      }

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

    }());

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

Eu tentei isso, mas agora tenho um problema diferente.O IDE realmente não entende myLibrary qualquer.

A maneira como estou resolvendo o problema agora é desta forma:

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

myLibrary = (function () {

  var someProp = "...";

  function someFunc() {
    ...
  }

  function someFunc2() {
    ...
  }

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

}());

Mas isso parece meio desajeitado e não consigo entender exatamente como o jQuery está fazendo isso.Outra dúvida que tenho é como lidar com funções com números arbitrários de parâmetros.

Por exemplo, jQuery.bind pode receber 2 ou 3 parâmetros, e o IDE não parece reclamar.Tentei fazer a mesma coisa com minha biblioteca, onde uma função poderia receber 0 argumentos ou 1 argumento.Porém, o IDE reclama e avisa que o número correto de parâmetros não está sendo enviado.Como faço para lidar com isso?

EDITAR

Estou começando a me perguntar se esse é um problema do Idea9 porque o jQuery tem o mesmo problema.Parece que não tenho esse problema em outros projetos.

Foi útil?

Solução

Estou usando a ideia com o padrão do módulo Yahoo e minhas obras de preenchimento automático. Google Padrão do módulo 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

com *1 e *2, marquei locais onde tentei concluir automaticamente.

Em *1 eu recebo um método de algum_constant e privatestuff e, se eu colocar isso. (AutoComplete), tenho acesso a todos os métodos e propriedades dentro do retorno {} bloco

Quando tento preenchimento automático no *2, recebo todos os métodos e propriedades no bloqueio de retorno {}. Alguns métodos do Concome e Privatestuff são Invisibile lá, porque são "privados".

Para mim, esse nível de preenchimento automático é muito bom.

Outras dicas

Eu acho que será ótimo se você ler algo sobre Douglas Crockford. Ele é o arquiteto na estrutura de Yahou Yui. E depois disso, você pode ter uma idéia melhor de como criar uma ótima estrutura. E para o parâmetro, existem 2 opções. 1.- Enviar por exemplo do objeto

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

E você pode verificar se a opção existe.

O segundo que não é ótimo é verificar se o parâmetro é indefinido.

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

E apenas um comentário, por que construir uma nova estrutura JavaScript? Use protótipo, jQuery, mootols, yui. Por que reinventar a roda?

Isto é uma resposta aos comentários feitos postagem de mwilcox.

Esse exemplo realmente funcionará.Desde myLibrary é definido sem var, ele é automaticamente colocado no namespace global e acessível como tal.Através do fechamento criado pela função autoexecutável, as variáveis ​​e métodos privados ainda estão acessíveis no myLibrary métodos.Você pode tentar isso facilmente colocando-o no Firebug ou Rhino.

Hoje em dia, não costumo esconder minhas variáveis, ou seja,Eu uso o padrão Pseudoclássico ou o padrão Prototípico e prefixo meu pretendido métodos privados com um _:

// 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() {}
};

Para evitar que meu código polua o namespace global, tenho um processo de construção que envolve meus módulos em um encerramento e exporta a API pública para o namespace.Esta técnica também é usada pelo jQuery.Você pode ver isso em seu código-fonte (veja intro.js e outro.js) em GitHub.

Isso permitiria que você usasse um padrão que permite que seu IDE (ou ctags com vim) veja sua API, ao mesmo tempo que evita a poluição do namespace global.

Eu escrevo minhas bibliotecas como esta:

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

new MyLibrary();

Dessa forma, em Geany (que usa CTAGs) MyLibrary é bem reconhecido (na maioria das vezes, por exemplo, o membro é reconhecido como uma função) e a conclusão automática parece funcionar. Eu não sei sobre o Idea9, mas você pode tentar dessa maneira (eu tenho um palpite, é um pouco mais evoluído que o CTAGS).

Eu recomendo que você não use variáveis ​​privadas, mas entendo que você deseja que elas sejam ocultadas do intellisense.É assim que eu faria:

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


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

})();

Dessa forma, você pode ter suas coisas privadas fechadas e sua biblioteca deve estar acessível.

[editado.Desajeitadamente, não incluí myLibrary na função anônima e ela não conseguiu ver os vars privados.opa.]

Aliás, minhas razões para variáveis ​​privadas serem ruins: http://clubajax.org/javascript-private-variables-are-evil/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top