Mootools odc. 3: Core
Odcinek trzeci kursu mootools i jednocześnie pierwszy stricte praktyczny. Części teoretycznej oczywiście też nie zabraknie, ale po raz pierwszy będzie można zobaczyć co to narzędzie potrafi w akcji. Nadszedł czas, aby zaznajomić się z rdzeniem frameworka.
Wprowadzenie
Core to element bazowy - jest niezbędny do działania całej reszty modułów. Oferuje on nam 15 funkcji - funkcji nie metod ponieważ nie są powiązane z żadnym obiektem. Są to:
boolean $chk(item)void $clear(timer)boolean $defined(object)function $arguments(i)function $emptyfunction $lambda(value)object $extend(original, extension)object $merge(obj1, obj2[, obj3[,...]])void $each(iterable, fn[, bind])mixed $pick(var1[, var2[, var3[, ...]]])number $random(min, max)array $splat(obj)number $time()mixed $try(fn[, fn, fn, fn, ...])mixed $type(object)
Mamy już pełną listę dostępnych funkcji, więc rozpoczynamy omawianie każdej z nich.
boolean $chk(item)
Sprawdza, czy dana zmienna jest zdefiniowana lub przyjęła wartość 0 - wtedy zwraca nam true. Najczęściej wykorzystuje się ją w funkcjach, aby sprawdzić, czy został przekazany nam dany parametr. Jeżeli jako testowany argument zostanie przekazane: false, null, "" (pusty łańcuch znaków) lub undefined otrzymamy false. Może służyć do obsługi opcjonalnych argumentów.
function add(one, two, three, four) {Gdybyśmy jednak nie użyli funkcji
var ret = one + two + three;
if ($chk(four)) ret += four;
return ret;
}
add(1, 2, 3); // 6
add(1, 2, 3, 5); // 11
add(1, 2, 3, 0); // 6$chk i a naszą zapisali:
function add(one, two, three, four) {Drugie wywołanie zwróciłoby
var ret = one + two + three + four;
return ret;
}
add(1, 2, 3, 5); // 11
add(1, 2, 3); // NaNNaN - Not a Number. Stałoby się tak ponieważ do 6 (1 + 2 + 3) dodalibyśmy undefined co nie może być poprawną operacją matematyczną. Jeżeli chodzi o przekazywanie obiektów do funkcji to samo $chk to zbyt mało, ale o tym za chwilę.
void $clear(timer)
Jedna z rzadziej używanych funkcji. Pozwala na usuwanie timerów. Timery to funkcje, które są wykonywane po określonym czasie (setTimeout) lub co określony czas (setInterval). Tworzenie timerów odbywa się poprzez 2 metody obiektu Function: delay i periodical lub wcześniej wspomniane natywne funkcje JavaScriptu. Malutki przykład (kto, komu i za co płaci zostawiam Waszej fantazji):
var count = 0;Zastosowanie? Np. przy okresowym pobieraniu jakichś danych z XHTTPRequest (popularne i błędnie określane mianem AJAXa).
var pay = function () {
if (++count > 3) {
$clear(pay);
alert('Dość się już napłaciłem');
} else
alert('Zapłaciłem');
}.periodical('2000');
boolean $defined(object)
Funkcja o niemal identycznym działaniu jak $chk. Jedyną różnicą jest to, że sprawdza, czy dana zmienna została zainicjalizowana (ustawiona), czyli nie jest undefined bądź null. Zupełnie jak isset w PHP. Jeżeli wartość została ustawiona zwraca true. Oczywiście literały (bezpośrednio wpisane wartości) zwracają prawdę;
var arg = $arguments(2);
$defined(arg); // true
$defined(1); // true
function fun(arg1, arg2) {
return $defined(arg1);
}
fun(); // false
fun(1); // true
fun(null, 2); // false
fun(false); // true
$defined(foo); // błąd
function $arguments(i)
Sposób działania tej funkcji może wydać się sporej części z Was dziwna, aczkolwiek jest to dosyć częsta praktyka w JavaScript. Zwracaną wartością jest funkcja. O ile sama praktyka zwracania funkcji bądź podstawiania ją pod zmienną jest nierzadko spotykana to samo wykorzystanie $arguments już nie. Mnie prawdę mówiąc nigdy się to nie zdarzyło (wolę używać arguments[i]), więc przykład też tylko tutorialowy:
var arg = $arguments(2);Jeżeli ktoś tego używa i poda sensowne wytłumaczenie czemu to będę wdzięczny, reszta może praktycznie o tym zapomnieć.
arg(3, 5, 9);
function $empty
Tworzy pustą funkcję - ot zagadka po co komuś pusta funkcja. Najczęściej wykorzystuje się ją jako pojemnik (placeholder) na metody w klasach. Zdaję sobie sprawę, że na razie to wysoki poziom abstrakcji - dojdziemy do klas wszystko stanie się łatwiejsze. $empty jest równoznaczne z zapisem funkcji pustej bez parametrów, czyli:
function() {}
$empty; // równoznaczny zapis
function $lambda(value)
Rzecz podobna do $empty - również tworzy funkcję z tą jednak różnicą, że zwraca ona podaną przez nas wartość. Poniżej dwa równoznaczne zapisy:
function() {Do czego może się nam to przydać? Znów do klas lub miejsc, gdzie wymagana jest funkcja, a nie konkretna wartość. Funkcja to recepta na wykonanie czegoś. Ktoś tworząc klasę starał się zrobić ją uniwersalnie, więc mamy możliwość podania funkcji, która po skomplikowanych obliczeniach zwróci jakąś wartość. Jednak dla innej osoby wystarczy, że poda gotowy wynik (jak np. nasze 1 z przykładu) - więc zapis z lambdą jest po prostu wygodniejszy. Prosty przykład:
return 1;
}
$lambda(1); // równoznaczny zapisfunction() {
return 1;
}
$lambda(1); // równoznaczny zapis
object $extend(original, extension)
Łączy ze sobą dwa obiekty. Do pierwszego zostają przepisane własności drugiego. Jeżeli klucze powtarzają się w obu obiektach zostają nadpisane przez te pochodzące z drugiego. Na żywo:
var maluch = {Wynik zaskakujący po połączeniu (zderzeniu) nie otrzymaliśmy pomarańczowego kawałka złomu.
ovner: 'Jan Kowalski',
color: 'czerwony',
abs: 'tak'
}
var porsche = {
ovner: 'Mirek Nowak',
color: 'żółty',
radio: 'nie'
}
var afterCrash = $extend(maluch, porsche);
/* afterCrash = {
ovner: 'Mirek Nowak',
color: 'żółty',
abs: 'tak',
radio: 'nie'
} */
object $merge(obj1, obj2[, obj3[,...]])
Łączy ze sobą dwa obiekty. Do pierwszego zostają przepisane własności drugiego. Jeżeli klucze powtarzają się w obu obiektach zostają nadpisane przez te pochodzące z drugiego. Na żywo:
var blonde = {W wyniku połączenia blondynki z rudą i brunetką otrzymaliśmy kobietę mądrą, choć niewysoką i całą menażerią. Jaka jest więc różnica między
IQ: 60,
height: 178,
pets: {
dog: 'Misiek',
cat: 'Bobik'
}
}
var redhead = {
IQ: 110,
height: 170,
pets: {
dog: 'Reksio',
alligator: 'Pusia'
}
}
var brunette = {
IQ: 140,
height: 162
}
var mix = $merge(blonde, redhead, brunette);
/* mix = {
IQ: 140,
height: 162,
pets: {
dog: 'Misiek',
cat: 'Bobik',
alligator: 'Pusia'
}
}
*/$extend, a $merge? Są dwie: $merge potrafi łączyć dowolnie wiele obiektów ze sobą oraz potrafi łączyć zagnieżdżone obiekty w obiektach (w naszym przykładzie zwierzaki). $merge może zawsze zastąpić $extend, odwrotnie już tak nie jest.
void $each(iterable, fn[, bind])
Kolejne odniesienie do PHP - wypisz wymaluj instrukcja foreach. Delikatnie tylko inna składnia aczkolwiek działanie to samo. Pierwszym parametrem jest tablica/obiekt, który chcemy przejść, drugim funkcja anonimowa (bo nie ma ona nazwy), która definiuje co chcemy zrobić:
$each(['pies','kot','rybka'], function(pet, index) {Parametry podstawianej funkcji anonimowej (oczywiście kolejność jest istotna i co więcej wskazuje częstość ich użycia - pierwszy zawsze, drugi rzadziej, trzeci mało kiedy):
console.log(index + '. ' + pet);
});
// wynik: "0. pies", "1.kot", "2.rybka"
- wartość
- indeks (numerowany od zera) dla tablic bądź klucz dla obiektów
- tablica bądź obiekt, który obecnie przetwarzamy
To samo możemy zastosować do obiektów (znów osoby ze znajomości PHP skojarzą tablice asocjacyjne):
var family = {
'mother': 'Anna',
'father': 'Jan',
'brother': ['Tomasz', 'Michał', 'Grzegorz'],
'sister': 'Monika'
}
$each(family, function(name, key) {
console.log(key + ' - ' + name);
});
// wynik: "mother - Anna", "father - Jan", "brother - Tomasz,Michał,Grzegorz", "sister - Monika"
W praktyce jednak częściej zapewne będziecie używać metody each obiektów Hash i Array.
mixed $pick(var1[, var2[, var3[, ...]]])
Zwraca pierwszy argument, który nie jest równy null lubnull właśnie jeżeli, każdy z argumentów jest null:
function test(a, b, c) {
return $pick(a, b, c);
}
test('jeden', 'dwa', 'trzy'); // jeden
test(false, true); // false
test(null, 'alfa', 'beta'); // alfa
test(); // null
test(null, null, null); // null
test(null, 'tekst', null); // tekst
test(null, null, 'kot'); // kot
test(a, null, 'kot'); // bład bo a nie zostało nigdzie zdefiniowane
number $random(min, max)
Losowa liczba z zakresu
alert("Pan, drogi studencie zaliczył dziś na: " + $random(2, 5));
array $splat(obj)
Zamienia każdy przekazany obiekt na jednoelementową tablicę chyba, że przekazano tablicę - wtedy zwraca tą samą nieprzetworzoną tablicę. Należy zwrócić uwagę, że funkcja ta nie konwertuje obiektów (object) na tablice, a po prostu wstawia go jako pierwszy element nowej tablicy.
var obj = {
cat: 'Miki',
dog: 'Rom'
}
$splat(obj); // [{cat: 'Miki', dog: 'Rom'}]
$splat(false); // [false]
$splat(1); // [1]
$splat([1, 5, 6]); // [1, 5, 6]
number $time()
Zwraca uniksowy znacznik czasu (timestamp):
$time(); // 1256758382146
mixed $try(fn[, fn, fn, fn, ...])
Funkcja próbuje wykonać funkcje przekazane jej jako parametry i zwraca wartość, którą jej zwróciła pierwsza funkcja, która została wykonana prawidłowo. Jeżeli żadna nie zostanie wykonana bezbłędnie zwraca null:
var fun1 = function () {
return 0;
}
var fun2 = function () {
return 2 / 0; // dzielenie przez zero nie jest błędem w rozumieniu funkcji $try
}
var fun3 = function () {
return a; // nie ma takiej zmiennej jak a
}
var fun4 = function () {
return Array.xyz(); // nie ma takiej metody jak xyz()
}
$try(fun1, fun2, fun3, fun4); // 0
$try(fun3, fun4); // null
$try(fun2, fun4); // Infinity
mixed $type(object)
Funkcja testuje czym jest przekazany jej argument (niczym wycofywane z PHP, a przynajmniej niezalecane, gettype). Może zwrócić string opisujący słownie, czym jest argument bądź false jeżeli jest wartością niesprecyzowaną (szczegóły poniżej):
- element - element drzewa DOM
- textnode - węzeł tekstowy DOM
- whitespace - węzeł tekstowy DOM, w którym są wyłącznie białe znaki (spacja, nowa linia, tabulacja, etc.)
- arguments - argumenty funkcji
- array - tablica
- object - obiekt
- string - łańcuch znaków
- number - liczba
- date - data
- boolean - wartość logiczna (true lub false)
- function - funkcja
- regexp - wyrażenie regularne
- class - klasa stworzona przez
new Classbądź rozszerzenie innej klasy - collection - kolekcja elementów DOM (np. zwrócone przez metody klasy
Elementsbądź natywne funkcje jak np. getElementByTagName) - window - obiekt
window - document - obiekt
document - false - jeżeli testowana wartość jest
undefined,null,NaNlub też żadną z powyższych
Przykłady użycia:
var str = "tekst";Gdzie tak naprawdę się ich używa? Np. do testowania przekazanych parametrów dla funkcji co pozwala w dosyć okrężny sposób stosować przeciążanie funkcji.
$type(str); // string
$type(document.getElementById('menu')); // element
function test(arg1) {
switch ($type(arg1)) {
case 'string': return 'Przekazano: ' + arg1; break;
case 'number': return Math.pow(arg1, 2); break;
default: alert('Błędny parametr');
}
}
test("kot"); // Przekazano: kot
test(2); // 4 - bo 2 do potęgi 2
test(false); // alert z komunikatem "Błędny parametr"
Podsumowanie
Możemy przyjąć, że na pewno połowę z tych funkcji będziecie stosować całkiem często. Macie już pewne podstawy do startowania z mootools, ale wierzcie mi lub nie - fura nauki jeszcze przed Wami. Cóż - nikt nie obiecywał, że nie będzie bolało.
Pytania, poprawki, błędy, uwagi? Ktoś mądry po to właśnie wymyślił komentarze, więc droga wolna.
PS. W tym tygodniu miały być dwie rzeczy Core i Browser. Wyszło samo Core bo jak widzicie wpis i tak zrobił się długi. Browser podepniemy pod jakąś mniejszą objętościowo notkę.
W następnym tygodniu w “MooTools”
Tablice, czyli klasa Array - spora i naprawdę potrzebna rzecz.
Listopad 3rd, 2009 - 18:09
Zaczyna się robić ciekawie! Dzięki!