jQuery vtičniki, tretji del

December 7th, 2009 by Krof Drakula Leave a reply »

Po drugem članku sledi tretji – tokrat bomo govorili o privzetih nastavitvah in parametrih funkcij, ki jih lahko uporabljamo znotraj jQuery vtičnikov.

Če še niste prebrali prejšnjega članka, potem to storite sedaj, ker bomo nadgradili snov prejšnjega s splošnimi primeri razširjanja objektov. Za vse tiste, ki vas zanima branje celotne serije člankov, pa lahko začnete s prvim člankom v seriji.

Ko sestavljamo svoj vtičnik za jQuery, se moramo odločiti, katere parametre želimo izpostaviti končnemu uporabniku, s katerimi bi ta nadziral izvajanje naših funkcij. Na tej točki se moramo seveda odločiti, katere parametre je smiselno izpostaviti kot nujne in katere kot parametre, ki jih ni potrebno podati.

V Javascriptu lahko argumente vsake funkcije zapišemo z eksplicitnimi parametri:

var myFunction = function(a, b) {
  alert("a = " + a.toString() + ", b = " + b.toString());
}

V tem primeru smo definirali funkcijo z dvema parametroma, a in b. Ko kličemo to funkcijo, jo lahko kličemo brez parametrov, lahko pa podamo poljubno število parametrov:

myFunction();
myFunction("Lorem");
myFunction("Lorem", "Ipsum");
myFunction("Lorem", "Ipsum", "Dolor", "Sit", "Amet");

Ko imamo definirano takšno funkcijo in podajamo spremenljivo število parametrov, se moramo zavedati enega pravila:

Če parametra funkciji ne podamo, potem je vrednost parametra enaka undefined.

Tako bi v prvem primeru bila a in b undefined, v drugem le b, v ostalih dveh primerih pa bi oba parametra imela podani vrednosti.

V čem se pa razlikujeta zadnja dva primera? Odgovor se skriva v arguments spremenljivki, ki je na voljo znotraj vsake funkcije – ta spremenljivka vsebuje seznam vrednosti vseh argumentov, podanih funkciji, ki jih lahko naslovimo s številčnim indeksom. Če se želimo sprehoditi po vseh podanih vrednostih, lahko znotraj funkcije izvedemo for zanko:

for(var i = 0; i < arguments.length; i++) {
  alert(arguments[i]);
}

Na tej točki je treba opozoriti, da čeprav se arguments spremenljivka obnaša kot array, to vseeno ni, ker ne vsebuje določenih metod, ki jih pričakujemo na teh objektih, vseeno pa je varno po njej iterirati na način, kot je prikazano zgoraj. Če na ta način definiramo sumacijsko funkcijo, lahko podamo poljubno število številčnih argumentov:

var sum = function() {
  var n = 0;
  for(var i = 0; i < arguments.length; i++) {
    n += arguments[i];
  }
  return n;
}

To funkcijo lahko uporabljamo na naslednji način:

sum(3, 18, 82, 35, 18, 92, 532, 823, 14, 42);

Ne glede na število parametrov bo funkcija vedno vrnila vsoto vseh podanih parametrov (če le noben izmed njih ni string).

Vseeno pa v takih primerih ne vemo, kateri parameter je bil podan v katerem kontekstu – ko smo imeli vmyFunction funkciji imenovana parametra a in b, smo vedeli, kateri je kateri, pri takšnih funkcijah pa ne vemo, v kakšnem zaporedju moramo podajati argumente, vsaj ne glede na podpis funkcije.

Še vedno lahko uporabljamo kombinacijo obojega, kot smo prej klicali funkcijo z več parametri, kot je bilo podanih, vendar se pa stvari zakomplicirajo, ko želimo podati samo enega izmed množice parametrov. Dober primer je, ko želimo podati le b:

myFunction(undefined, "Ipsum");

Ta primer seveda deluje pravilno (če seveda izvzamemo dejstvo, da funkcija v primeru undefined vrže napako, kar je pričakovano), ampak postane okoren način klicanja funkcij, ko se število klicev na ta način poveča. Kako se torej izognemo temu problemu (ali bolje rečeno, ga rešimo) in še vedno ohranimo poimenovane parametre brez vnaprej določenega vrstnega reda?

Rešitev so Javascript objekti. Le-ti držijo lastnosti, po katerih lahko iteriramo in na katere se lahko sklicujemo. Če želimo podati funkciji poimenovane parametre, ji lahko kot edini parameter pošljemo Javascript objekt s pravimi lastnostmi:

myFunction({ a: "Lorem", b: "Ipsum });

Tu smo uporabili krajšo notacijo za ustvarjanje novega Object objekta (new Object()). Če spremenimo našo prvotno funkcijo, jo lahko oblikujemo tako, da sprejme edini parameter, iz katerega črpa svoje parametre:

var myFunction = function(params) {
  alert("a = " + params.a.toString() + ", b = " + params.b.toString());
}

Funkcionalnost je identična prejšnji; pojavi pa se problem, ko želimo podati le enega izmed parametrov, saj klic na objekt (params.a in params.b) zahteva obstoj lastnosti na params objektu – če te lastnosti ni, klic na toString() vrže napako.

V tem primeru lahko uporabimo $.extend() funkcijo, ki smo jo v prejšnjem članku uporabili za razširjanje jQuery objekta, in jo na podoben način uporabili za nastavljanje privzetih vrednosti funkcije:

var myFunction = function(params) {
  var myDefaults = { a: "Parameter A", b: "Parameter B" };
  params = $.extend(myDefaults, params);
  alert("a = " + params.a.toString() + ", b = " + params.b.toString());
}

S tem smo pa rešili problem. Ko podamo funkciji objekt z lastnosti, naša funkcija uporabi myDefaultsobjekt, katerega lastnosti povozi z objektom, ki ga podamo funkciji. Rezultat je nov objekt, ki ga zapišemo nazaj v params spremenljivko, ki sedaj vsebuje vse parametre, ki smo jih podali, manjkajoče lastnosti pa potem prevzame iz myDefaults objekta. Funkcija tako nikoli ne javi napake, tudi če podamo samo enega izmed parametrov:

myFunction({ b: "Ipsum" });

S tem tudi zaključujemo tretji članek v seriji; v naslednjem bomo pa govorili o tem, kako tehniko podajanja parametrov iz tega članka uporabimo za privzete vrednosti v jQuery vtičniku in kako te privzete nastavitve izpostavimo končnemu uporabniku, ko jih bo ta želel spremeniti.

Advertisement

3 comments

  1. BV says:

    Zanimivi članki…se bo treba tudi enkrat tega lotit… :) vem, kje začeti….

  2. Krof Drakula says:

    Ti se pa tega spravljaš lotit že eno leto. :P