« 1 2 »
Autor Zpráva
javascript
Profil *
Dobrý den, mám objekt s metodami a jedná má v sobě jQuery, jak z nějho zavolám jinou metodu?:

function Objekt()
{

....this.funkceJedna = function()
....{
........$.ajax({
............type: "POST",
............url: "neco.php",
............data: "",
............success: function(msg){
................(tady nevim co, this by mi ukazovalo na jQuery).funkceDva();
............}
........});
....}

....this.funkceDva = function()
....{
........alert('ok');
....}

}

děkuju moc
Joker
Profil
javascript:
Jestli jsem dobře pochopil dotaz, mělo by stačit this...

Mimochodem, proč nahrazovat odsazení tečkami, když tu máme to pěkné tlačítko na vkládání kódu?
javascript
Profil *
Firebug mi při this hlásí:

this.funkceDva is not a function
anonymous(Object name=msg) - ui (řádek 202)
success() - jquery-1.3.2.js (řádek 3645)
anonymous(35) - jquery-1.3.2.js (řádek 3602)
[Break on this error] this.funkceDva();\n - ui (řádek 202)

soubor ui, řádek 202:

        $.ajax({
            type: "POST",
            url: "neco.php",
            data: "",
            success: function(msg){     
               this.funkceDva(); //tohle je řádek 202
            }             
        });


a jQuery, řádek 3645:

		function success(){
			// If a local callback was specified, fire it and pass it the data
			if ( s.success )
				s.success( data, status ); // tohle je řádek 3645

			// Fire the global callback
			if ( s.global )
				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
		}
_es
Profil
javascript
Asi máš trochu chaos v kľúčovom slove this a v rôznych spôsoboch definovania funkcií.
Akým spôsobom voláš tú funkciu s podivným názvom Objekt?
javascript
Profil *
Já mam teď strašný bordel v definování objektů a metod v javascriptu vůbec. :(
Co je vlastně správně? Já nemůžu na internetu najít správný řešení.


function Objekt()
{

    this.promenna = 0;

    this.metoda = function()
    {
       ....
    }

}


nebo:


Objekt = {
     promena: 0,
     metoda: function(){

    }
    

}


?

Děkuju, teĎ opravdu nevím. :(
_es
Profil
javascript
Načo chceš vytvárať nejaké vlastné objekty, v JavaScripte to neprináša až také výhody.
A keď už, tak si najprv poriadne naštuduj základy syntaxe JavaScriptu.
Prvý kód vytvorí funkciu nazvanú Objekt. Tá funkcia je obvykle volaná ako konštruktor, napríklad:
var x = new Objekt();
a premenná x bude potom objekt s metódami či vlastnosťami (V JS to je jedno) premenna a metoda, premenna je číslo 0 a metoda je funkcia. Definovanie metódy metoda je navyše nevhodné, lebo bude pre každý takto vytvorený objekt vytváraná extra funkcia.
Druhý kód vytvorí už priamo objekt skoro rovnaký ako v prvom kóde.
Aichi
Profil *
_esNačo chceš vytvárať nejaké vlastné objekty, v JavaScripte to neprináša až také výhody.

Zapouzdření ti asi nic neříká...

javascript Dobrý den, mám objekt s metodami a jedná má v sobě jQuery, jak z nějho zavolám jinou metodu?:

Celý problém je, že v metodě objektu je this ten objekt, nicméně při návratu z httprequestu (nebo např. při volání timeOutu), se kontext objektu ztrácí a this je ve většině případů window. Takže jediné co musíš, je tzv. zbindovat metodu objektu tak aby si pamatovala svůj kontext. v kódu v prvním příspěvku je nutné v metodě jedna udělat tento kód:

this.funkceDva = function(){return this.funkceDva.apply(this, arguments)};


pomocí apply do vlastnosti funkceDva uložíš původní funkceDva, ale nyní si již pamatuje objekt se kterým je svázána. Pak by mělo stačit v konfiguračním objektu pro ajax dát

success: this.funkceDva()
a do ní pak chodí argument msg
_es
Profil
Aichi
Zapouzdření ti asi nic neříká...
Takže miesto nejakého jednoduchého riešenia to bude mať javascript zložito "zapuzdrené".
Hlavne že bude "in" a "OOP".
Keby to javascript naozaj vedel rozumne využiť, tak sa tu nebude pýtať takéto otázky.

this.funkceDva = function(){
Prototypový objekt nepoznáš?
Načo niečo také zložité?
Aichi
Profil *
Prototypový objekt nepoznáš?
Načo niečo také zložité?


Jestli si myslíš, že ti pomůžou prototypy k tomu abys obešel prudu JS, že do svých callbacků vyžaduje pouze funkce, tak mi to ukaž.

Takže miesto nejakého jednoduchého riešenia to bude mať javascript zložito "zapuzdrené".

Pokud to budeš brát takhle, tak se to nikdy nenaučí a zůstane u mraku funkcí. To že to jQuery nepodporuje je jeho největší vada.
_es
Profil
Aichi
pouze funkce, tak mi to ukaž.
Nie je mi jasné, čo presne má ten objekt vyrobený pomocou konštruktoru - funkcie Objekt robiť, aj sám javascript priznáva, že má v tom zmätok, no metódy je obvykle správne k objektom priradiť:
Objekt.prototype.funkceJedna = function(){/*nejaký rozumný kód*/};
Aichi
Profil *
_esNie je mi jasné,
stále si mi nepředvedl jak to udělat, na funkčnosti metod řešení nezávisí.
_es
Profil
Aichi
stále si mi nepředvedl jak to udělat

Urobiť čo presne? Čo je to "riešenie"?
Keď nie je jasná otázka, tak nemôže byť ani presná odpoveď.
Aichi
Profil *
_es
takže tu jen prudíš? Psal jsi mi:

„this.funkceDva = function(){“
Prototypový objekt nepoznáš?
Načo niečo také zložité?


chci vědět jak pomocí prototypu uděláš nabindování, které dělám přes apply aby to nebylo tak složité.
_es
Profil
Aichi
Stále mi nie je jasné, na čo sa vlastne pýtaš, ak je funkcia konštruktoru nazvaná Objekt:
function Objekt(){/*Definícia konštruktoru*/}
Objekt.prototype.funkceJedna = function(){/*nejaký rozumný kód*/};
var x = new Objekt, y = new Objekt;
x.funkceJedna(); // Zavolanie motódy funkceJedna nad objektom x
y.funkceJedna(); // Zavolanie motódy funkceJedna nad objektom y
A nie je potrebné vytvárať pre každý vytváraný objekt extra objekt funkcie, ešte k tomu vnorenej, ale stačí jedna spoločná funkcia.
Aichi
Profil
_es
a jak použití prototypu řeší volání metody jako callback, pokud je to metoda objektu? O tom je ta otázka, ne o tom jeslti použít nebo nepoužít prototypy.
jelc
Profil *
_es
A jak to pomuze s tim problemem ohledne jQuery?
Nijak to nezmeni to ze v puvodnim kodu ma uzivatel 'javascript' problem s tim na co reprezentuje this, v jeho pripade uvnitr callbacku neodkazuje na objekt v jehoz kontextu je definovana metoda, pokud tomu dobre rozumim.
Ondráš
Profil *
I při definici

Objekt.prototype.funkceJedna = function() { ... }


budu v háji, pokud funkceJedna využívá klíčové slovo "this" a já pak budu psát

var instance = new Objekt();
nejake_volani_ajaxu_s_callbackem(instance.funkceJedna);


To proto, že ajaxové callbacky se volají v kontextu window. Je zcela mylné se domnívat, že "funkceJedna" je nějakým způsobem svázána s objektem, u kterého byla definována jako vlastnost. Takový požadavek je navíc nesmyslný.

Když už chci v ajax callbacku volat funkci, která ve svém těle používá this, musím zařídit, aby this při volání nabývalo správné hodnoty. Například takto:

var instance = new Objekt();
var funkce_volana_v_callbacku = function() { return instance.funkceJedna.apply(instance, arguments); }
nejake_volani_ajaxu_s_callbackem(funkce_volana_v_callbacku);


Celkově si myslím, že dokud človek _NAPROSTO_PŘESNĚ_ nechápe, jak v JS funguje magické slůvko "this", je lepší se této konstrukci totálně vyhýbat.

A co se týče příspěvku číslo pět - oba způsoby jsou pro tento účel naprosto ekvivalentní. Rozdíl v definici metod přímo a přes prototypový objekt se totiž projeví až tehdy, budu-li ze své "třídy" chtít dědit třídy další.
_es
Profil
Aichi
pomocí apply do vlastnosti funkceDva uložíš původní funkceDva, ale nyní si již pamatuje objekt se kterým je svázána.

Tá metóda funkceJedna definovaná cez prototyp môže predsa pristupovať k objektom x a y cez kľúčové slovo this, netreba nejako špeciálne nastavovať, čo si má "pamätať".
Ak som to stále rozumne nezodpovedal, tak tu skús dať nejaký funkčný, čo najjednoduchší kód, bez JQuery, s tým tvojim viazaním, napríklad len s alert() a pod. Aby som pochopil, čo vlastne myslíš pod tým "volaním metódy jako callback".
Aichi
Profil
_es pokud by byla pravda to co píšeš, tedy že prototyp definuje this pro funkci, fungoval by následující příklad:


var Objekt = function() {
  this.x = 31;
}

Objekt.prototype.funkce = function() {
  alert(this.x);
}

var o = new Objekt();
var f = o.funkce;
f();


nicméně se funkce f() vykoná ve scope window a ne "o",...
_es
Profil
Ondráš
Konečne začínam trochu chápať o čo ide.
No stále je trochu neefektívne vytvárať pre každý objekt extra funkciu, čo si bude pamätať objekt, s ktorým je zviazaná a možno bude využitá.
To už môžu byť tie objekty rovno funkcie, keď majú byť využívané hlavne ako funkcie, s funkciou je možné tiež narábať ako s objektom.
Alebo v prototype definovať nejakú metódu, ktorá vyrobí funkciu "zviazanú" s objektom. Napríklad:

Objekt.prototype.f = function(){var o = this; return function(){/*kód pristupujúci k viazanému objektu o*/};};
var instance = new Objekt();
nejake_volani_ajaxu_s_callbackem(instance.f());
Ondráš
Profil *
Jak jsem psal v předcházejícím příspěvku, ve finále je to (pokud opomeneme dědičnost) v tomhle konkrétním případě úplně jedno. Pokud má každá "instance" disponovat metodou volatelnou v callbacku, budeme mít pro X instancí X metod, takže je šumák, jestli je definujeme "na požádání" (tvůj poslední příklad), nebo "paušálně" (this.metoda = function() { ... }).

Tak či onak je nesystémové řešení v callbackové funkci (či jejím generátoru) psát
var XXX = this;
/* jakýkoliv kód pracující s XXX */

neboť výsledný kód pak závisí na pojmenování "správné" reference na instanci, v jejímž kontextu chceme metodu vykonávat. Pisatel takového kódu tak vlastně obchází používání klíčového slova "this" jen proto, že s ním neumí správně pracovat. Korektní řešení je ve funkcích opravdu vždy psát "this.cokoliv" a starat se o to, aby byla funkce volaná ve správném kontextu (jak píše Aichi).

Summary: Z pohledu volání metody "jako callback" (například přes setTimeout nebo onReadyStateChange) jsou následující tři deklarace zcela ekvivalentní:

var objekt = {
  x: 31,
  mojeFunkce: function() { alert(this.x); }
}

var Objekt = function() {
  this.x = 31;
  this.mojeFunkce = function() { alert(this.x); }
}

var Objekt = function() {
  this.x = 31;
}
Objekt.prototype.mojeFunkce = function() { alert(this.x); }


Skutečnost, že třetí způsob přináší v jiných oblastech významné výhody (dědičnost, sdílení metod), je pro téma tohoto vlákna - a patrně i jeho autora - nedůležitá.
_es
Profil
Ondráš
takže je šumák, jestli je definujeme "na požádání" (tvůj poslední příklad), nebo "paušálně" (this.metoda = function() { ... }).
Definícia "na požiadanie" vytvorí funkciu keď je treba, a po dokončení obvykle objekt tej funkcie automaticky zanikne.
Zatiaľ čo "paušálne" znamená, že ak je napríklad 1 000 objektov, tak je tiež definovaných 1 000 objektov funkcií, bez ohľadu na to, či sú potrebné a po dokončení stále existujú.

Pisatel takového kódu tak vlastně obchází používání klíčového slova "this" jen proto, že s ním neumí správně pracovat
Môže ho nepoužívať preto, že mu jeho použitie práve nevyhovuje. No je tiež možné definovať funkciu "na požiadanie", používajúcu this, v prototype:
Objekt.prototype.f = function(){
  var This=this, Arg=arguments;
  return function(){(function(){/*kód pristupujúci k viazanému objektu cez this*/}).apply(This, Arg);};
  return function(){(function(){/*kód pristupujúci k viazanému objektu cez this*/}).apply(This, arguments);};
};
Opravené podľa [#25] Ondráš
Skutečnost, že třetí způsob přináší v jiných oblastech významné výhody (dědičnost, sdílení metod), je pro téma tohoto vlákna - a patrně i jeho autora - nedůležitá.
Bolo tu zdôraznené, ako je veľmi dobré pre zakladateľa vlákna sa to "OOP" naučiť, no súčasne mu nie sú zdôrazňované základné veci, ako že sa spoločné metódy definujú v prototype. Otázne je, načo mu potom celý ten objektový obal vlastne bude.
JavaScript je skôr vhodný na používanie už hotových objektov, než na nejaké rozsiahlejšie objektové programovanie.
Ondráš
Profil *
Definícia "na požiadanie" vytvorí funkciu keď je treba
Zatiaľ čo "paušálne" znamená, že ak je napríklad 1 000 objektov, tak je tiež definovaných 1 000 objektov funkcií
Jenže v praxi he situace většinou taková, že ajaxové volání je prováděno _opakovaně_ z _malého_ množství instancí. Jinými slovy, vyrobím pár instancí (tj. pár paušálních funkcí), které pak opakovaně volám. V tomto případě je výroba "na požádání" dokonce ještě horší, protože novou funkci vyrábí při každém požadavku. Pokud je počet požadavků větší než počet instancí, ještě si pohorším.

Mimochodem, také preferuji definici metod přes vlastnost konstruktoru "prototype". A ano, funkce vyrobené na požádání se dají kešovat. To tu ale nikde zmíněno není a jen jsem chtěl ukázat, že situace rozhodně není černobílá a je krátkozraké dopředu hlaholit "postup A je špatný, postup B je vždy lepší". Tohle už je skutečně offtopic, neb to s původní otázkou vůbec nesouvisí. Proto bych toto téma opustil.

Môže ho nepoužívať preto, že mu jeho použitie práve nevyhovuje.
Jasně, na to má svaté právo. Ale "koho chleba jíš, toho píseň zpívej"; jednou je jazyk postavený na nějakých konstrukcích a pokud je člověk odmítá respektovat, pak by se to měl buď naučit, nebo si jít hledat jazyk jiný. Tvorba komplikovaných obezliček a drbání se levou rukou za pravým uchem je pak _přesně_ to, co potenciálního kolemjdoucího spolehlivě odradí. I toto sem nepatří a nebudeme to řešit.

No je tiež možné definovať funkciu "na požiadanie", používajúcu this, v prototype:
Ano, právě jsi zduplikoval kód z Aichiho prvního příspěvku (akorát tam má překlep - poslední dvě "this" mají být ve tvé variantě This), respektive z třetí ukázky mého prvního příspěvku. Jsem rád, že jsme konečně dokonvergovali k řešení zmíněném už v prvních příspěvcích, totiž (anonymní) bindovací funkci. Tím je toto vlákno snad definitivně zodpovězené.

Mimochodem, není mi jasný účel proměnné "Arg" - do vnitřní anonymní funkce by správně měly probublat parametry té vnější anonymní (např. nějaká ajaxová data), nikoliv parametry posílané při tvorbě "na požádání".

Bolo tu zdôraznené, ako je veľmi dobré pre zakladateľa vlákna sa to "OOP" naučiť,
Ne, to tu zdůrazněné nebylo. O OOP se mluvilo jen v souvislosti s tím, že jeho nepoužívání je dříve nebo později cesta do pekel a že používání "objektů" v JS (tento termín lze v kontextu JS interpretovat mnoha způsoby, takže je dost zavádějící) je dobrý postup. Však také všechny mé ukázky nějaký objekt definují.
Ještě vidím v nějakém dřívějším příspěvku tvrzení „Načo chceš vytvárať nejaké vlastné objekty, v JavaScripte to neprináša až také výhody. “, které ovšem není podepřené žádným argumentem a pokud se chceš pokusit ho obhajovat, doporučoval bych nové vlákno.

JavaScript je skôr vhodný na používanie už hotových objektov, než na nejaké rozsiahlejšie objektové programovanie.
Tohle bych zhodnotil jako naprostý (opět nepodložený) výkřik do tmy :)
_es
Profil
Ondráš
Ale "koho chleba jíš, toho píseň zpívej"; jednou je jazyk postavený na nějakých konstrukcích a pokud je člověk odmítá respektovat, pak by se to měl buď naučit, nebo si jít hledat jazyk jiný.
Ak je k objektu x priradená funkcia-metóda f, jedno akým spôsobom, tak správne použitie tej funkcie má byť x.f(). "Vytrhnutie" tej funkcie od objektu x alebo podobných objektov a použitie funkcie inak, napríklad pomocou apply a vkladaním toho volania do ďalšej funkcie, nejakej rekurzie a pod., mi pripadá dosť neprirodzené. Nejaké čisté "OOP" riešenie toho, o čo išlo, asi v JavaScripte nie je. Takže je to vlastne len o tom, ktoré riešenie je menej špinavé.

akorát tam má překlep“ „poslední dvě "this" mají být ve tvé variantě This
Ako to má mať Aichi správne? Tomu nerozumiem, predsa v tom okomentovanom kóde by malo byť this a This to isté.

do vnitřní anonymní funkce by správně měly probublat parametry té vnější anonymní (např. nějaká ajaxová data)
Dá sa to aj pri takýmto spôsobom vyrobenej funkcii zabezpečiť? Alebo len stačí úplne vypustiť premennú Arg?

které ovšem není podepřené žádným argumentem
Z otázok zakladateľa vlákna je zrejmé, že si tým vytváraním objektov v tomto prípade veľmi nepomohol, ani nejako nezjednodušil. A keby to neriešil, možno by to mal už funkčné. Tvrdenie, že v niektorých iných jazykoch má to "OOP" viac výhod sa mi nezdá klamlivé. To "OOP" predsa nespočíva v bezhlavom strkaní všetkého do hocijakých objektov, ale v použití tak, aby to bolo užitočné. Tá otázka možno nebola celkom v poriadku, prospešné by však bolo, ak by na ňu dokázal javascript odpovedať.

Tohle bych zhodnotil jako naprostý (opět nepodložený) výkřik do tmy :)
Vo väčšine prípadov je tak JavaScript používaný a to nielen začiatočníkmi, možno ty si svetlá výnimka.
Ondráš
Profil *
Ako to má mať Aichi správne? Tomu nerozumiem, predsa v tom okomentovanom kóde by malo byť this a This to isté.

Aichiho kód má být takhle:
var This = this;
var puvodniFunkceDva = this.funkceDva;
this.funkceDva = function(){return puvodniFunkceDva.apply(This, arguments)};


Tohle řešení využívá triku, kdy původní funkceDva (ať už byla definována libovolným způsobem) přestává být běžně dostupná (je držena jako "privátní" proměnná "puvodniFunkceDva") a pod jejím název se skrývá nová ("anonymní") funkce, která tu předchozí (vždy) volá ve správném kontextu.
Dokonce to lze řešit i bez té privátní proměnné a odkaz na původní funkceDva držet ve scope chainu nějakého generátoru:
function zbinduj(objekt, funkce) {return function() { return funkce.apply(objekt, arguments); }}
this.funkceDva = zbinduj(this, this.funkceDva);


Dá sa to aj pri takýmto spôsobom vyrobenej funkcii zabezpečiť? Alebo len stačí úplne vypustiť premennú Arg?

Jasně, v tvojí ukázce
  return function(){(function(){/*kód pristupujúci k viazanému objektu cez this*/}).apply(This, arguments);};

Pole "arguments" obsahuje parametry té funkce, ve které je použito - v našem případě té vnější anonymní. A tyhle jsou pomocí apply pěkně "přeposlány" do té vnitřní anonymní :)
_es
Profil
Ondráš:
Aichiho kód má být takhle:
Vzťahuje sa to vôbec rozumne k dotazu javascripta?
Nedochádzalo by vlastne nelogicky k predefinovaniu funkceDva pri každom zavolaní funkceJedna a pri opakovanom volaní funkceJedna by sa sa funkceDva nestávala stále viac a viac vnorenejšou funkciou?
Ondráš
Profil *
Nedochádzalo by vlastne nelogicky k predefinovaniu funkceDva pri každom zavolaní funkceJedna a pri opakovanom volaní funkceJedna by sa sa funkceDva nestávala stále viac a viac vnorenejšou funkciou?

Ten kód, o kterém teď mluvíme, se nemá vykonávat při volání funkceJedna, ale jen jednou při inicializaci objektu (tj. např. v "konstruktoru"). Pokud by se volal z funkceJedna, bylo by to přesně jak píšeš - neustálé obalování.
_es
Profil
Ten kód, o kterém teď mluvíme, se nemá vykonávat při volání funkceJedna, ale jen jednou při inicializaci objektu (tj. např. v "konstruktoru").
Ale javascript dostal radu, aby ten kód dal do funkcie funkceJedna, ktorej inštancia je vytváraná a priraďovaná k objektu pri jeho vytvorení, čo nemá zmysel. javascript mal skôr dostať radu, že celý ten konštruktor je zlý a nie ako ho "vylepšiť".
Ondráš
Profil *
Ale javascript dostal radu, aby ten kód dal do funkcie funkceJedna

To tedy nevidím, kde takovou radu dostal. Zmíněný kód patří v prvním příspěvku před poslední zavírací složenou závorku, respektive kamkoliv do těla funkce Objekt za definicí funkceDva.
_es
Profil
Ondráš
To tedy nevidím, kde takovou radu dostal.

[#7](Aichi) „... v kódu v prvním příspěvku je nutné v metodě jedna udělat tento kód: this.funkceDva = function(){...
« 1 2 »

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:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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

0