Autor Zpráva
joe
Profil
Ahoj, mám kód:

var foo = foo || {};
foo.bar = foo.bar || {};


foo.bar.Example = function() {
    // kód
};


var example = new foo.bar.Example();

Potřeboval bych z proměnné example jakýmkoli způsobem získat text, že jde o "foo.bar.Example" (a s tímto stringem dále v kódu pracovat), nešlo by to nějak? Stačilo by mi to například jen v Chrome, mělo by to sloužit jen k testovacím účelům... Díky za nápady, jak by to šlo udělat, aniž bych musel psát do každé třídy toString.
Chamurappi
Profil
Reaguji na joe:
On je trochu problém, že ta tvá funkce vlastně žádné jméno nemá. O tom, že je přiřazená do nějakého foo.bar.Example, netuší. Když je použita jako konstruktor, tak se ani nezná s foo.bar. Jinými slovy foo.bar.Example není název konstruktoru, ale jen poněkud neosobní cesta k anonymní funkci z řádku 5, která se použije jako konstruktor. Proto si myslím, že na to žádná magie neexistuje.

Mohl bys místo obyčejného přiřazení použít vlastní funkci, která jednak provede přiřazení a jednak na prototype té funkce kamsi přilepí i tuto identifikaci (nejspíš pole názvů, třeba ["foo", "bar", "Example"]). Asi z toho nic moc hezkého nevyleze.

K čemu ten název potřebuješ?
_es
Profil
joe:
Ono je v princípe nevhodné namiesto samotných premenných pracovať s ich náhradami za nejaké textové reťazce - z hľadiska výkonu a pod. Môžeš do funkcie - konštruktoru priradiť nejakú vlastnosť, ktorá potom ide zistiť aj z objektu vytvoreného z tejto funkcia ako konštruktoru - ak nebola prepísaná jeho vlastnosť constructor.
foo.bar.Example.identifikacia = "foo.bar.Example";
alert(example.constructor.identifikacia) // "foo.bar.Example"
joe
Profil
Chamurappi:
Máš samozřejmě pravdu, trochu nevhodně jsem to popsal, sám beru foo.bar.Example vlastně za "konstruktor", protože přesně pomocí něho vytvářím instance, je v něm jen uložena anonymní funkce.

Když ale v Chromu loguju, co je v example, do konzole mi vypíše, že je o foo.bar.Example, a to je super, protože když mi jiné nástroje vypíšou, že jde jen o objekt, tak mi to moc nepomůže.

Chamurappi & _es:

Řetězce se mi právě nikde moc používat nechce a to ani třeba do těch toString metod, které by vyřešily můj problém. Protože budu výsledný kód obfuskovat a řetězcem bych vlastně všechno odkryl (ne, že by to byl problém, ale je to zbytečné psaní a dokážu si představit, že by toString vracelo něco úplně jiného jenom proto, protože kód nové třídy byl převzatý a na přepsání se zapomnělo :)).

Chtěl bych to jen pro informaci vývojáře a usnadnění práce, nechtěl bych pořád otvírat konzoli a tam to ve výstupu někde hledat. Stačilo by, kdyby šel třeba nějakým způsobem zachytit (získat) výstup v Chrome consoli (například)
1Pupik1989
Profil
Jde to, ale musíš rekurzivně projet celý objekt window. Nic jiného mě nenapadá.

var foo = foo || {};
foo.bar = foo.bar || {};
 
foo.bar.Example = function(){

};
 
var example = new foo.bar.Example();


function getConstructorName(instance,obj){
  var f;
  var result;
  
  if(!obj){ obj = window; }

  for(var name in obj){
    f = obj[name];

    if(typeof f === 'function' && f.toString().indexOf('[native code]') === -1){
      if(instance instanceof f){  return name; }
    }else if((!!f) && (f.constructor === Object)){
      if(result = getConstructorName(instance,f)){
        return name+'.'+result;
      }
    }
  }
  
  return false;
};

console.log(getConstructorName(example)); //foo.bar.Example

Žádná krása to ale není. Možná by se to dalo zrychlit, kdyby někdo přišel jak oddělit definované objekty od nativních.

Asi bych to pak přiřadil do Function.prototype.getConstructorName třeba.
Chamurappi
Profil
Reaguji na 1Pupika1989:
Tohle mě také napadlo, ale než jsem to sepsal, vlezl mi do toho oběd :-)

Ve for-in bys možná měl použít hasOwnProperty, abys neprojížděl i přes věci přidané na prototype (moc jsem nad tím nepřemýšlel, nemohla by tam bez toho vzniknout nekonečná smyčka?).

musíš rekurzivně projet celý objekt window
Možná by nemusel jít skrz celý window, zřejmě má jen malé množství svých hlavních objektů, které ho zajímají.
Případně by šlo ten rekurzivní průchod provést jednorázově na začátku a předpřipravit si pole všeho, co může být konstruktor, a to pak rychleji projet (pokud nepřidává konstruktory dodatečně).
1Pupik1989
Profil
Chamurappi:
Ve for-in bys možná měl použít hasOwnProperty, abys neprojížděl i přes věci přidané na prototype (moc jsem nad tím nepřemýšlel, nemohla by tam bez toho vzniknout nekonečná smyčka?).

Teď si mi připomněl, že tam vůbec nemám vyřešenou situaci, kdy se funkci přidá hodnota. Čili momentálně jí ten kód úplně vynechá.

if(instance instanceof f){  
  return name; 
}else if(result = getConstructorName(instance,f)){
  return name+'.'+result;
}

Teď už by to mělo projít v pořádku.

var foo = foo || {};
foo.bar = foo.bar || function(){

};

foo.bar.prototype = {
  method: function(){}
};

//foo.bar.foo = foo;
 
foo.bar.Example = function(){

};



 
var example = new foo.bar.Example();


function getConstructorName(instance,obj){
  var f;
  var result;
  
  if(!obj){ obj = window; }

  for(var name in obj){
    f = obj[name];
    
    if(!obj.hasOwnProperty(name)){ continue; }
    
    if(typeof f === 'function' && f.toString().indexOf('[native code]') === -1){
      if(instance instanceof f){  
        return name; 
      }else if(result = getConstructorName(instance,f)){
        return name+'.'+result;
      }
    }else if((!!f) && f.constructor === Object){
      if(result = getConstructorName(instance,f)){
        return name+'.'+result;
      }
    }
  }
  
  return false;
}; 


Nicméně pokud se naskytne případ foo.bar.foo = foo;, tak to skončí zacyklením. Takže by se muselo vytvořit nějaké pole, aby nevznikly duplicity při hledání.

Teď ještě zkusím nejdřív vygenerovat strom, jak jsi psal.
joe
Profil
1Pupik1989:
Tak to je super, díky! :) Ještě jsem připsal k if(instance instanceof f){ doplnění podmínky o && instance.constructor === f, aby mi to vždy nenašlo jen předka, když využívám dědičnost.
1Pupik1989
Profil
Nebo další možnost jak psal Chamurappi.

A možná kdyby si ještě do toho hodnot objektu přidal i počet klíčů, tak by to stačilo vygenerovat jen jednou.
Pak by stačilo ve funkci na vyhledávání porovnávat aktuální počet klíčů s uloženým počtem.

Bylo by to vlastně něco na styl "NodeListu".

//edit: Mohlo by to vypadat zhruba takto.

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: