Autor Zpráva
tester
Profil *
Mám takový problém. Iniciuju různé proměnné, hlavně pole uvnitř funkce. Abych to zkrátil tak dám sem jen dvě proměnné. Potřeboval bych, aby se ty proměnné nepřepsaly kdykoliv znovu zavolám funkci (rekurzivně). Prostě jak jednou provedu iniciaci, aby funkce znovu neiniciovala dané proměnné. Jak to udělat? Ideální by byla statická proměnná, ale jak docílit něčeho jako static x; if (!x) x=...???

Tohle je jen taková blbost pro zjednodušení:
String.prototype.findStrings = function (params) {
var s="hello word";
var i=10;
i--;
if (i<0)
  return true;
else
 s.findStrings();
}
TomášK
Profil
Vytvoř si ještě jednu funkci pojmenovanou třeba findStringsInternal, která bude mít ty proměnné jako parametry a bude se používat v tom rekurzivní volání. findStrings bude jen wrapper pro findStringsInternal.

function findStrings() {
  return findStringsInternal(10);
}

function  findStringsInternal(i) {
  if (i < 0) 
    return true;
  else
    return findStringsInternal(i - 1);
}
tester
Profil *
Ono těch proměnných je ale fakt hodně:
  var s = null, prev = null, prevEscaped = null, typq = null, 
      typp = null, depRB = 0, depSB = 0;  
  var pArr=[], iArr=[], oObj;
  oObj = {
    length: 0, 
    results: []
    };
  var action = null;
  var PA=[],PB=[];
  var PX=[], PXB=[], PXA=[],
      PQ=[], PR=[], PS=[], PE=[], PN=[];
  var isX=null, isXB=null, isXA=null, isQ=null, isR=null, isS=null, isE=null, isN=null;
Já myslel jestli to nejde udělat tak, že jak je jednou deklaruju v jedné funkci v té druhé budou přístupné automaticky. Prostě abych nemusel předávat přes parametry. Chtěl jsem to zkrátit co nejvíce, jinak bych mohl všechno strčit do wrapperu a přistupovat ke členům takto P.A,P.B,P.X,P.XB,P.XA ovšem bez tečky je rychlejší zápis a kratší kód.


TomášK:
A to co popisuješ jde to i s prototypem? Já to potřebuju na String.prototype.findStrings
tester
Profil *
Skvělé už jsem to vyřešil:

  String.prototype.inc = (function () {
    var i = 0;

    var some = function () {
        i += 1;
        alert(i);
        if (i > 9)
          return true;
        some();
    }

    return init;
  })();
  
  var s = "Hello World";
  s.inc();



na konci mělo být
return some;
Radek9
Profil
tester:
Je ti ale jasné, že tohle bude mít pro všechny stringy stejnou proměnnou i? Co má ta funkce konkrétně dělat? Určitě by se to dalo vymyslet lépe.
tester
Profil *
Radek9:
Ta funkce nejprve (action===0) parsuje řetězec a během toho shromažďuje statistiky o řetězcích. Pak ji chci zavolat znova na to výsledné pole s argumentem (action=1) a má rekurzivně prohledávat části řetězců. To řešení je hlavně kvůli té druhé fázi (action===1).

Pochopil jsem ale problém - problém nastastal už po dokončení první fáze. Protože když chci opět zavolat tu funkci, tak ona mi už neskočí na začátek aby provedla novou iniciaci, ale použije staré hodnoty (action===0) čímž opakuje tu první akci...
tester
Profil *
Nedaří se mi to zprovoznit, kde je chyba:

String.prototype.findStrings = (function () {
  var action = 'split';
  var params = ',';
  var init = function (action = 'split', params = ',') {
    console.log("init");
    this.stringSplit();
  }
 var stringSplit = function (action) {
  if (action=="split")
    return this.init();
  // pokud nepředám argument action, tak parsuje řetězec a vrací objekt
  }
 var stringSearch = function (action) {
  if (action=="split")
    return this.init();
  // pokud nepredám argument action ale params tak hledá substringy, vrac9 objekt  
  }
  return init;
})();

Hlásí mi to chybu na řádku #6.
this.stringSplit(); že this není String. This je window a neobsahuje funkci stringSplit.

Jak to opravit?

Implementace má být taková:
var test = '#a > :matches(.b, #c)'; 
test.findStrings('split', "," );
var result = test.findStrings( 'search', { params ... } );



Ještě to zkrátím:

String.prototype.findStrings = (function () {
  var action = 'split';
  var params = ',';
  var init = function (action = 'split', params = ',') 
  { this.stringSplit(); }
  var stringSplit = function (action) 
  { return this.init(); }
 var stringSearch = function (action) 
  {return this.init(); }
  return init;
})();



Co to má dělat:
Když zavolám test.findStrings('split');
má 1) iniciovat hodnoty zavoláním init, 2) pak má zavolat stringSplit tak že this má být řetězec test.
Když zavolám var results = test.findStrings( 'search', { params ... } ); 1) znovu se mají iniciovat hodnoty, zpracují se argumenty z obj. params 2) pak se má zavolat stringsSearch přitom this má být text.
Chamurappi
Profil
Reaguji na testera:
this.stringSplit(); že this není String.
Ale je. Funkci init přiřazuješ do String.prototype.findStrings, takže při jejím zavolání je v this to, na čem byla zavolána (tedy instance stringu).
Potíž je, že stringy nemají metodu stringSplit, protože ta tvá funkce stringSplit je jen obyčejná lokální funkce, není na žádném objektu, na žádném prototypu…

Jak to opravit?
Buď navěsíš všechny metody, které chceš volat na this, na prototype, nebo je budeš mít jako lokální funkce (takhle, jak je máš) a budeš je volat bez this (a ani ony samotné neuvidí this).

Celkově mi to přijde takové podivně vymyšlené. Můj programátorský cit skřípe nehty o tabuli, funkci specifickou pro selektory bych nikdy nedával na String.prototype, je příliš specifická a konkrétní pro jedno použití na to, aby si zasloužila sepnout se všemi řetězci. Ale když myslíš, že s ní budeš v této podobě šťastný…

Mimochodem, můžu se zeptat, co to vlastně tvoříš? Sice je mi sympatické, že si na spoustu otázek dokážeš najít řešení sám a ochotně se o něj podělíš s námi, ale vzhledem k tomu, kolik toho řešíš, si říkám, jestli třeba neexistuje snazší cesta k cíli, která by napadla někoho z nás, kdybychom znali záměr.
tester
Profil *
Takže jen stačilo odstranit var stringSplit a dát tam String.prototype.stringSplit...

Mě to příjde celkem pohodlné a elegantní řešení protože staří napsat text.stringSplit('split'); a potom text.stringSearch('search', params); ... no dělá to to že to najde podstringy a přitom bude uplatňovat rekurzivní regexp match. Funkce je zaměřená na závorky (,) a [,] a uvozovky "",''. Během prvního zavolání se to rozparsuje a navíc se posbírají užitečné informace o stringu. V následujícím zavolání může dojít k rekurzivnímu hledání, ale jelikož se tam skrytě vytvořily ty statistiky, tak se to celé může značně urychlit. Prostě pokud určitý znak není v řetězci tak k rekurzivnímu spuštění vůbec nedojde. Dovedu si představit že by se funkce přejmenovala jinak ale proč, když v zásadě hledám ve stringu?
Chamurappi
Profil
Reaguji na testera:
Já byl zvědavý spíš na žádaný výsledek celého snažení. Pochopil jsem, že tvoříš zřejmě nějaké rozšíření pro Firefox… které bude dělat co?
tester
Profil *
Chamurappi:
Toho je hodně, má to více modulů a to na čem teď pracuju je jen jedna malá část celého rozšíření (které bude fungovat na Firefoxu a Chrome). Víš co, nech se překvapit až to bude hotové. Řeším teď ale problém s tím že ta funkce kterou jsem tu uved mi (v její rozšířené verzi se všemi proměnnými nefunguje. Ty proměnné, které jsem deklaroval ve findStrings jsou sice přístupné, ale nejsou iniciované. Já vše iniciuju v init. Vezmu pole s parametry a ukládám regulární výrazy do pole PXB. Pak k tomu chci přistoupit zevnitř stringSearch ale pole PXB má v tu chvíli délku 0. U jiných proměnných jako action, params ty jsem nastavil přes argumenty funkce: a, p... action=a, params=p; tím jsem dočasně vyřešil problém s těmi nenastavenými proměnnými u action a params. No ale takto řešit nějakých 20-30 proměnných je dost neefektivní. Tady je link na zdrojový kód:
paste.ofcode.org/e4um5jG9bNWJyrgnwC3Y2u

implementace:
var test = '#a > :find-first .b';
var separators = test.findStrings('split');
var result = test.findStrings( 'search', regexParams );

Pro snadnější orientaci se orientuj podle čísel:
iniciace: 1.0
1.1 je příprava všech proměnných, které jsou určeny pro stringSearch
2.0 je stringSplit, to můžeš přeskočit protože tam jdou jen dvě proměnné dovnitř a jedna ven
3.0 stringSearch je ta problematická funkce
3.1 zde potřebuji zpřístupnit iniciované pole s parametry PXB
tester
Profil *
Už jsem to vyřešil. Napadlo mě zkusit odladit tu iniciaci. Našel jsem tam hned několik bugů jako slovíčka breaky mimo blocky switch; nebo for ( var i; místo for ( var i =0; takže buď nemohlo dojít k iniciaci nebo by to pole nemohlo být "prolezeno". Ještě nedeklarované proměnné.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: