Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00347 005250 14100013 na godz. na dobę w sumie
JavaScript. Zasady programowania obiektowego - ebook/pdf
JavaScript. Zasady programowania obiektowego - ebook/pdf
Autor: Liczba stron: 128
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-9595-9 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> javascript - programowanie
Porównaj ceny (książka, ebook, audiobook).

Programiści pracujący na co dzień z użyciem języków takich, jak Java, C# czy C++, z pewnym pobłażaniem patrzą na JavaScript. Traktują go jako język nie do końca obiektowy, w którym można napisać program działający bez tworzenia klas i obiektów. Są w błędzie! JavaScript to język o ogromnych możliwościach, pozwalający na obiektowe tworzenie programów. Nie wierzysz? Sięgnij po tę książkę i przekonaj się na własnej skórze!

Znajdziesz w niej szczegółowe omówienie obiektowych elementów języka JavaScript. Poznasz podstawowe różnice pomiędzy typami prostymi i referencyjnymi oraz dowiesz się, jak sobie z nimi radzić w trakcie pracy z tym językiem. W kolejnych rozdziałach zaznajomisz się ze specyfiką funkcji w JavaScripcie oraz nauczysz się rozpoznawać charakterystyczne elementy obiektów. Ponadto Twoją uwagę powinien zwrócić rozdział poświęcony konstruktorom, prototypom oraz technikom dziedziczenia. Ta książka jest obowiązkową lekturą dla wszystkich programistów tworzących programy w języku JavaScript.

Dzięki tej książce:

Poznaj obiektowy charakter języka JavaScript!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: The Principles of Object-Oriented JavaScript Tłumaczenie: Aleksander Lamża ISBN: 978-83-246-9592-8 Original edition Copyright © 2014 by Nicholas C. Zakas. ISBN 978-1-59327-540-2, published by No Starch Press. All rights reserved. Published by arrangement with No Starch Press, Inc. Polish language edition copyright © 2014 by Helion S.A. All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/jascpo Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:258)ci O AUTORZE ..................................................................... 7 WST(cid:125)P .............................................................................. 9 WPROWADZENIE ........................................................... 11 1 TYPY PROSTE I REFERENCJE ......................................... 15 Czym s(cid:200) typy? ....................................................................................... 16 Typy proste .......................................................................................... 17 Identyfikowanie typów prostych ...................................................... 19 Metody typów prostych ................................................................... 20 Typy referencyjne ................................................................................ 21 Tworzenie obiektów ........................................................................ 21 Dereferencja obiektów .................................................................... 22 Dodawanie i usuwanie w(cid:239)a(cid:258)ciwo(cid:258)ci ................................................. 23 Tworzenie instancji wbudowanych typów ........................................... 24 Litera(cid:239)y ............................................................................................. 24 Litera(cid:239)y obiektów i tablic .................................................................. 25 Litera(cid:239)y funkcji .................................................................................. 26 Litera(cid:239)y wyra(cid:285)e(cid:241) regularnych ........................................................... 26 Dost(cid:218)p do w(cid:239)a(cid:258)ciwo(cid:258)ci ........................................................................ 27 Identyfikowanie typów referencyjnych ................................................... 28 Kup książkęPoleć książkę Identyfikowanie tablic ...........................................................................30 Typy opakowuj(cid:200)ce ................................................................................30 Podsumowanie .....................................................................................33 2 FUNKCJE ........................................................................ 35 Deklaracje kontra wyra(cid:285)enia ................................................................36 Funkcje jako warto(cid:258)ci ...........................................................................37 Parametry .............................................................................................39 Przeci(cid:200)(cid:285)anie ..........................................................................................41 Metody obiektów .................................................................................43 Obiekt this ........................................................................................44 Modyfikowanie this ...........................................................................45 Podsumowanie .....................................................................................48 3 OBIEKTY ........................................................................ 51 Definiowanie w(cid:239)a(cid:258)ciwo(cid:258)ci .....................................................................51 Wykrywanie w(cid:239)a(cid:258)ciwo(cid:258)ci ......................................................................53 Usuwanie w(cid:239)a(cid:258)ciwo(cid:258)ci ..........................................................................55 Wyliczenia .............................................................................................56 Rodzaje w(cid:239)a(cid:258)ciwo(cid:258)ci .............................................................................58 Atrybuty w(cid:239)a(cid:258)ciwo(cid:258)ci ............................................................................60 Wspólne atrybuty .............................................................................60 Atrybuty w(cid:239)a(cid:258)ciwo(cid:258)ci danych ...........................................................62 Atrybuty w(cid:239)a(cid:258)ciwo(cid:258)ci funkcji dost(cid:218)powych ......................................64 Definiowanie wielu w(cid:239)a(cid:258)ciwo(cid:258)ci .......................................................66 Pobieranie atrybutów w(cid:239)a(cid:258)ciwo(cid:258)ci ...................................................67 Zapobieganie modyfikowaniu obiektu ....................................................68 Zapobieganie rozszerzaniu ...............................................................68 Piecz(cid:218)towanie obiektów ..................................................................69 Zamra(cid:285)anie obiektów .......................................................................70 Podsumowanie .....................................................................................71 4 KONSTRUKTORY I PROTOTYPY ................................... 73 Konstruktory ........................................................................................73 Prototypy ..............................................................................................78 W(cid:239)a(cid:258)ciwo(cid:258)(cid:202) [[Prototype]] .................................................................79 U(cid:285)ywanie prototypów z konstruktorami .........................................82 4 S p i s t r e (cid:258) c i Kup książkęPoleć książkę Modyfikowanie prototypów ............................................................. 86 Prototypy wbudowanych obiektów ................................................. 88 Podsumowanie ..................................................................................... 89 5 DZIEDZICZENIE ............................................................. 91 (cid:146)a(cid:241)cuchy prototypów i Object.prototype ........................................... 91 Metody dziedziczone po Object.prototype ..................................... 92 Modyfikowanie prototypu Object.prototype ................................... 94 Dziedziczenie obiektów ....................................................................... 96 Dziedziczenie konstruktorów .............................................................. 99 Zaw(cid:239)aszczanie konstruktora .............................................................. 103 Uzyskiwanie dost(cid:218)pu do metod supertypu ........................................ 104 Podsumowanie ................................................................................... 106 6 WZORCE TWORZENIA OBIEKTÓW ............................... 107 Prywatne i uprzywilejowane sk(cid:239)adniki obiektów ............................... 108 Wzorzec modu(cid:239)u ............................................................................ 108 Prywatne sk(cid:239)adniki w konstruktorach ............................................ 110 Domieszki .......................................................................................... 113 Zabezpieczenie zasi(cid:218)gu w konstruktorach ........................................ 120 Podsumowanie ................................................................................... 122 SKOROWIDZ ................................................................ 123 S p i s t r e (cid:258) c i 5 Kup książkęPoleć książkę 6 S p i s t r e (cid:258) c i Kup książkęPoleć książkę 1 Typy proste i referencje WI(cid:125)KSZO(cid:165)(cid:109) PROGRAMISTÓW UCZY SI(cid:125) PROGRAMOWANIA OBIEKTOWEGO NA PRZYK(cid:146)ADZIE J(cid:125)ZYKÓW BAZUJ(cid:107)CYCH NA KLASACH, TAKICH JAK JAVA LUB C#. PRZY PIERWSZYM zetkni(cid:218)ciu z JavaScriptem mo(cid:285)na si(cid:218) poczu(cid:202) zdezo- rientowanym, poniewa(cid:285) w tym j(cid:218)zyku poj(cid:218)cie klas formalnie nie istnieje. Pracy nad kodem nie rozpoczyna si(cid:218) wi(cid:218)c od ich zdefiniowania, tylko od razu tworzy si(cid:218) potrzebne struk- tury danych. Brak klas poci(cid:200)ga za sob(cid:200) pewne konsekwencje — skoro nie ma klas, nie ma te(cid:285) pakietów. W j(cid:218)zykach takich jak Java nazwy pakietów i klas definiuj(cid:200) zarówno typy u(cid:285)ywanych w kodzie obiektów, jak i roz- mieszczenie plików oraz folderów w projekcie, natomiast w JavaScripcie nic nie jest narzucone, wi(cid:218)c o struktur(cid:218) plików musimy zadba(cid:202) sami. Nie- którzy programi(cid:258)ci staraj(cid:200) si(cid:218) stosowa(cid:202) rozwi(cid:200)zania z innych j(cid:218)zyków, na- tomiast inni korzystaj(cid:200) z elastyczno(cid:258)ci JavaScriptu i podchodz(cid:200) do pro- blemu w ca(cid:239)kiem nowy sposób. Co prawda dla stawiaj(cid:200)cych pierwsze kroki programistów ta swoboda mo(cid:285)e sta(cid:202) si(cid:218) przyczyn(cid:200) nieporozumie(cid:241) Kup książkęPoleć książkę i problemów, ale kiedy si(cid:218) przywyknie do specyfiki JavaScriptu, oka(cid:285)e si(cid:218), (cid:285)e to niezwykle efektywny i wygodny j(cid:218)zyk programowania. Przej(cid:258)cie z klasycznych j(cid:218)zyków obiektowych na JavaScript mo(cid:285)e u(cid:239)atwia(cid:202) to, (cid:285)e on równie(cid:285) bazuje na obiektach — przewa(cid:285)nie zapisuje si(cid:218) w nich dane i umieszcza funkcje. Tak naprawd(cid:218) w JavaScripcie nawet funkcje s(cid:200) obiektami, co czyni je najistotniejszymi elementami j(cid:218)zyka. Zrozumienie obiektowo(cid:258)ci w JavaScripcie i nauczenie si(cid:218) korzystania z obiektów s(cid:200) kluczowe dla zrozumienia JavaScriptu jako j(cid:218)zyka. Obiekty mo(cid:285)na tworzy(cid:202) w dowolnym momencie, niejako z marszu. Dotyczy to równie(cid:285) w(cid:239)a(cid:258)ciwo(cid:258)ci obiektów — mo(cid:285)na je dodawa(cid:202) i usuwa(cid:202), kiedy tyl- ko oka(cid:285)e si(cid:218) to konieczne. Poza tym elastyczno(cid:258)(cid:202) obiektów w JavaScrip- cie pozwala na stosowanie ciekawych i przydatnych wzorców, których nie da si(cid:218) zrealizowa(cid:202) w wielu innych j(cid:218)zykach. Ten rozdzia(cid:239) jest po(cid:258)wi(cid:218)cony dwóm podstawowym typom danych w JavaScripcie: typom prostym oraz referencjom. Mimo (cid:285)e dost(cid:218)p do zmiennych obu typów jest realizowany przez obiekty, zachowuj(cid:200) si(cid:218) one inaczej, wi(cid:218)c konieczne jest zrozumienie dziel(cid:200)cych je ró(cid:285)nic. Czym s(cid:200) typy? Mimo (cid:285)e w JavaScripcie nie stosuje si(cid:218) poj(cid:218)cia klas, funkcjonuj(cid:200) dwa ro- dzaje typów danych: typy proste i referencje. Typy proste (ang. primitives) s(cid:239)u(cid:285)(cid:200) do zapisywania danych w prostej postaci, natomiast w przypadku typów referencyjnych (ang. references) dane s(cid:200) zapisywane w obiektach, do których (a w(cid:239)a(cid:258)ciwie ich lokalizacji w pami(cid:218)ci) prowadzi referencja. Co ciekawe, JavaScript pozwala traktowa(cid:202) typy proste jak referencje, dzi(cid:218)ki czemu z punktu widzenia programisty j(cid:218)zyk jest bardziej spójny. W wielu innych j(cid:218)zykach istnieje (cid:258)cis(cid:239)e rozró(cid:285)nienie mi(cid:218)dzy tymi dwoma typami danych. Zmienna typu prostego jest przechowywana na stosie, a referencja na stercie. W JavaScripcie jest to rozwi(cid:200)zane zupe(cid:239)- nie inaczej — zmienna jest zapisywana w obiekcie zmiennych. Proste warto(cid:258)ci s(cid:200) przechowywane bezpo(cid:258)rednio w tym obiekcie, a w przypad- ku referencji w obiekcie zmiennej jest zapisany wska(cid:283)nik do lokalizacji obiektu w pami(cid:218)ci. Z dalszej lektury tego rozdzia(cid:239)u dowiesz si(cid:218), (cid:285)e mimo (cid:285)e pozornie typy te s(cid:200) do siebie podobne, w wielu sytuacjach zachowuj(cid:200) si(cid:218) zupe(cid:239)nie inaczej. 16 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę Typy proste Typy proste reprezentuj(cid:200) dane zapisane bezpo(cid:258)rednio w takiej formie, w jakiej wyst(cid:218)puj(cid:200), jak cho(cid:202)by warto(cid:258)ci true czy 25. W JavaScripcie ist- nieje pi(cid:218)(cid:202) typów prostych: boolean number string warto(cid:258)(cid:202) logiczna true albo false liczbowa warto(cid:258)(cid:202) ca(cid:239)kowita lub zmiennoprzecinkowa znak lub (cid:239)a(cid:241)cuch znaków uj(cid:218)ty w cudzys(cid:239)owy lub apostrofy (w JavaScripcie nie ma odr(cid:218)bnego typu dla pojedynczego znaku) typ prosty posiadaj(cid:200)cy tylko jedn(cid:200) warto(cid:258)(cid:202): null null undefined typ prosty posiadaj(cid:200)cy tylko jedn(cid:200) warto(cid:258)(cid:202): undefined (jest to warto(cid:258)(cid:202) przypisywana do zmiennej, która nie zosta(cid:239)a jeszcze zainicjalizowana) Pierwsze trzy typy (boolean, number i string) zachowuj(cid:200) si(cid:218) podobnie, natomiast dwa ostatnie (null i undefined) s(cid:200) traktowane inaczej, co zosta- nie szczegó(cid:239)owo opisane w dalszej cz(cid:218)(cid:258)ci rozdzia(cid:239)u. Warto(cid:258)ci wszystkich typów prostych maj(cid:200) reprezentacj(cid:218) w postaci litera(cid:239)ów. Litera(cid:239)y to te warto(cid:258)ci, które nie znajduj(cid:200) si(cid:218) w zmiennych, czyli na przyk(cid:239)ad zapisane w kodzie imi(cid:218) lub cena. Poni(cid:285)ej kilka przyk(cid:239)adów u(cid:285)ycia litera(cid:239)ów oma- wianych typów prostych: // string var name = Nicholas ; var selection = a ; // number var count = 25; var cost = 1.51; // boolean var found = true; // null var object = null; // undefined var flag = undefined; var ref; // warto(cid:286)(cid:252) undefined zostanie przypisana automatycznie W JavaScripcie, podobnie jak w wielu innych j(cid:218)zykach, zmienna typu prostego przechowuje warto(cid:258)(cid:202) (a nie wska(cid:283)nik do obiektu). Przypisanie T y p y p r o s t e i r e fe r e n c j e 17 Kup książkęPoleć książkę warto(cid:258)ci do takiej zmiennej polega wi(cid:218)c na utworzeniu kopii warto(cid:258)ci i zapi- saniu jej w zmiennej. St(cid:200)d wniosek, (cid:285)e je(cid:258)li do zmiennej przypisze si(cid:218) inn(cid:200) zmienn(cid:200), ka(cid:285)da z nich b(cid:218)dzie przechowywa(cid:239)a w(cid:239)asn(cid:200) kopi(cid:218) tej samej warto(cid:258)ci. Ilustruje to poni(cid:285)szy przyk(cid:239)ad: var color1 = czerwony ; var color2 = color1; Najpierw zmiennej color1 jest przypisywana warto(cid:258)(cid:202) czerwony . Na- st(cid:218)pnie zmiennej color2 jest przypisywana warto(cid:258)(cid:202) zmiennej color1, czyli czerwony . Mimo (cid:285)e obie zmienne maj(cid:200) t(cid:218) sam(cid:200) warto(cid:258)(cid:202), nie s(cid:200) w (cid:285)aden sposób ze sob(cid:200) powi(cid:200)zane, wi(cid:218)c je(cid:258)li zmieni si(cid:218) warto(cid:258)(cid:202) pierw- szej zmiennej, nie wp(cid:239)ynie to na drug(cid:200) (i odwrotnie). Wynika to z tego, (cid:285)e warto(cid:258)ci tych zmiennych s(cid:200) przechowywane w innych miejscach, co ilustruje rysunek 1.1. Rysunek 1.1. Obiekt zmiennej Podsumowuj(cid:200)c, zmienne typów prostych zajmuj(cid:200) odr(cid:218)bne miejsca w pami(cid:218)ci, wi(cid:218)c zmiany warto(cid:258)ci jednej zmiennej nie wp(cid:239)ywaj(cid:200) na inne zmienne. Oto jeszcze jeden przyk(cid:239)ad: var color1 = czerwony ; var color2 = color1; console.log(color1); // czerwony console.log(color2); // czerwony color1 = niebieski ; console.log(color1); // niebieski console.log(color2); // czerwony 18 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę W powy(cid:285)szym kodzie zmieniamy warto(cid:258)(cid:202) zmiennej color1 na niebie- ski , co nie wp(cid:239)ywa na oryginaln(cid:200) warto(cid:258)(cid:202) ( czerwony ) zmiennej color2. Identyfikowanie typów prostych Najlepszym sposobem okre(cid:258)lenia typu jest u(cid:285)ycie operatora typeof. Dzia(cid:239)a on ze wszystkimi zmiennymi i zwraca tekstow(cid:200) reprezentacj(cid:218) typu da- nych. W przypadku (cid:239)a(cid:241)cuchów tekstowych, liczb, warto(cid:258)ci logicznych i typu undefined operator dzia(cid:239)a w przewidywalny sposób, co wida(cid:202) w po- ni(cid:285)szym przyk(cid:239)adzie: console.log(typeof Nicholas ); // string console.log(typeof 10); // number console.log(typeof 5.1); // number console.log(typeof true); // boolean console.log(typeof undefined); // undefined Jak mo(cid:285)na si(cid:218) spodziewa(cid:202), operator typeof zwraca string , je(cid:258)li warto(cid:258)(cid:202) jest (cid:239)a(cid:241)cuchem tekstowym, number w przypadku liczb (bez wzgl(cid:218)- du na to, czy to liczba ca(cid:239)kowita, czy zmiennoprzecinkowa), boolean dla warto(cid:258)ci logicznych oraz undefined — w sytuacji gdy warto(cid:258)(cid:202) nie jest zdefiniowana. Sprawy si(cid:218) komplikuj(cid:200) w przypadku typu null. Niejednego programist(cid:218) zdziwi wynik wykonania poni(cid:285)szego kodu: console.log(typeof null); // object Operator typeof dla warto(cid:258)ci null zwraca object . Dlaczego obiekt, skoro to typ null? Sprawa jest dyskusyjna (TC39, czyli komitet odpowie- dzialny za zaprojektowanie i utrzymywanie JavaScriptu, przyzna(cid:239), (cid:285)e to b(cid:239)(cid:200)d), ale je(cid:258)li przyjmiemy, (cid:285)e null jest pustym wska(cid:283)nikiem do obiektu, rezultat object mo(cid:285)na uzna(cid:202) za uzasadniony. Najlepszym sposobem na sprawdzenie, czy warto(cid:258)(cid:202) to null, jest bez- po(cid:258)rednie porównanie: console.log(value === null); // true albo false T y p y p r o s t e i r e fe r e n c j e 19 Kup książkęPoleć książkę PORÓWNYWANIE BEZ ZMIANY TYPU Zwró(cid:202) uwag(cid:218), (cid:285)e w powy(cid:285)szym przyk(cid:239)adzie zosta(cid:239) zastosowany ope- rator potrójnego znaku równo(cid:258)ci (===), a nie standardowy (==). Wyni- ka to z tego, (cid:285)e potrójny operator nie wymusza zmiany typu porów- nywanych zmiennych. Poni(cid:285)szy przyk(cid:239)ad pomo(cid:285)e zrozumie(cid:202), dlaczego to takie wa(cid:285)ne: console.log( 5 == 5); // true console.log( 5 === 5); // false console.log(undefined == null); // true console.log(undefined === null); // false W przypadku zastosowania podwójnego znaku równo(cid:258)ci (cid:239)a(cid:241)cuch 5 i liczba 5 s(cid:200) równe, poniewa(cid:285) przed wykonaniem porównania (cid:239)a(cid:241)cuch zostaje przekonwertowany na liczb(cid:218). Operator potrójnego znaku równo(cid:258)ci nie uzna tych dwóch warto(cid:258)ci za równe, poniewa(cid:285) s(cid:200) inne- go typu. Podobnie sprawa wygl(cid:200)da w przypadku porównywania un- defined i null. Wniosek st(cid:200)d prosty — je(cid:258)li chcemy sprawdzi(cid:202), czy ja- ka(cid:258) warto(cid:258)(cid:202) jest null, musimy zastosowa(cid:202) potrójny znak równo(cid:258)ci, tak by by(cid:239) brany pod uwag(cid:218) równie(cid:285) typ. Metody typów prostych Mimo (cid:285)e (cid:239)a(cid:241)cuchy, liczby i warto(cid:258)ci logiczne s(cid:200) typami prostymi, maj(cid:200) metody (wyj(cid:200)tkiem s(cid:200) jednak typy null i undefined). Pod wzgl(cid:218)dem licz- by przydatnych metod wyró(cid:285)nia si(cid:218) typ string. Kilka z nich zosta(cid:239)o przedstawionych na poni(cid:285)szym listingu: var name = Nicholas ; var lowercaseName = name.toLowerCase(); // zamienia na ma(cid:225)e znaki var firstLetter = name.charAt(0); // zwraca pierwszy znak var middleOfName = name.substring(2, 5); // zwraca sekwencj(cid:266) znaków 2 - 4 var count = 10; var fixedCount = count.toFixed(2); // konwertuje na (cid:225)a(cid:276)cuch 10.00 var hexCount = count.toString(16); // konwertuje na (cid:225)a(cid:276)cuch a var flag = true; var stringFlag = flag.toString(); // konwertuje na (cid:225)a(cid:276)cuch true 20 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę UWAGA Na warto(cid:258)ciach typów prostych — mimo (cid:285)e nie s(cid:200) obiektami — mo(cid:285)na wywo(cid:239)ywa(cid:202) metody. Odpowiadaj(cid:200) za to mechanizmy Java- Scriptu, dzi(cid:218)ki którym warto(cid:258)ci te wydaj(cid:200) si(cid:218) obiektami, a to podnosi spójno(cid:258)(cid:202) j(cid:218)zyka. Typy referencyjne Typy referencyjne reprezentuj(cid:200) w JavaScripcie obiekty. Referencje to in- stancje typów referencyjnych, wi(cid:218)c mo(cid:285)na je uzna(cid:202) za synonim obiektów (w dalszej cz(cid:218)(cid:258)ci rozdzia(cid:239)u terminy te b(cid:218)d(cid:200) stosowane zamiennie). Obiekt jest nieuporz(cid:200)dkowan(cid:200) list(cid:200) w(cid:239)a(cid:258)ciwo(cid:258)ci z(cid:239)o(cid:285)onych z nazwy (b(cid:218)d(cid:200)cej zawsze (cid:239)a(cid:241)cuchami) i warto(cid:258)ci. W przypadku gdy warto(cid:258)ci(cid:200) w(cid:239)a(cid:258)ciwo(cid:258)ci jest funkcja, nazywa si(cid:218) j(cid:200) metod(cid:200). Funkcje s(cid:200) tak naprawd(cid:218) referencja- mi, wi(cid:218)c istnieje drobna ró(cid:285)nica mi(cid:218)dzy w(cid:239)a(cid:258)ciwo(cid:258)ci(cid:200) przechowuj(cid:200)c(cid:200) — powiedzmy — tablic(cid:218) a tak(cid:200), która zawiera funkcj(cid:218) (oczywi(cid:258)cie poza tym, (cid:285)e funkcj(cid:218) mo(cid:285)na wywo(cid:239)a(cid:202), a tablic(cid:218) nie). Zanim zacznie si(cid:218) korzysta(cid:202) z obiektu, trzeba go utworzy(cid:202). Tworzenie obiektów Obiekty w JavaScripcie dobrze jest sobie wyobrazi(cid:202) jako tablice asocja- cyjne (patrz rysunek 1.2). Rysunek 1.2. Struktura obiektu Istnieje kilka sposobów tworzenia obiektów (instancji). Pierwszym z nich jest u(cid:285)ycie operatora new w po(cid:239)(cid:200)czeniu z konstruktorem obiektu. Kon- struktor to funkcja, która jest u(cid:285)ywana przez operator new (mo(cid:285)e to by(cid:202) do- wolna funkcja). W JavaScripcie przyj(cid:218)to konwencj(cid:218) rozpoczynania nazw konstruktorów wielk(cid:200) liter(cid:200), by odró(cid:285)ni(cid:202) je od zwyk(cid:239)ych funkcji. Poni(cid:285)- szy kod tworzy instancj(cid:218) ogólnego obiektu i zapisuje referencj(cid:218) do niego w zmiennej object: T y p y p r o s t e i r e fe r e n c j e 21 Kup książkęPoleć książkę var object = new Object(); W przypadku typów referencyjnych obiekty nie s(cid:200) zapisywane bez- po(cid:258)rednio w zmiennej, do której s(cid:200) przypisywane, wi(cid:218)c zmienna object z powy(cid:285)szego przyk(cid:239)adu nie zawiera utworzonego obiektu. Przechowy- wany jest za to wska(cid:283)nik (czyli referencja) do lokalizacji w pami(cid:218)ci, gdzie znajduje si(cid:218) obiekt. Jest to podstawowa ró(cid:285)nica mi(cid:218)dzy obiektami i warto- (cid:258)ciami typów prostych, które s(cid:200) przechowywane bezpo(cid:258)rednio w zmiennej. Po przypisaniu obiektu do zmiennej zostaje w niej tak naprawd(cid:218) zapi- sany wska(cid:283)nik. Gdyby(cid:258)my t(cid:218) zmienn(cid:200) przypisali innej zmiennej, obie prze- chowywa(cid:239)yby kopi(cid:218) wska(cid:283)nika, który prowadzi do tego samego obiektu: var object1 = new Object(); var object2 = object1; W tym kodzie najpierw jest tworzony obiekt (za pomoc(cid:200) operatora new), a referencja do niego jest zapisywana w zmiennej object1. Nast(cid:218)p- nie zmienna ta jest przypisywana zmiennej object2. W tej chwili istnieje nadal tylko jedna instancja (utworzona w pierwszym wierszu kodu), ale referencja do niej jest przechowywana w dwóch zmiennych, co wida(cid:202) na rysunku 1.3. Rysunek 1.3. Dwie zmienne wskazuj(cid:200)ce ten sam obiekt Dereferencja obiektów W j(cid:218)zyku JavaScript jest stosowany mechanizm od(cid:258)miecania pami(cid:218)ci (ang. garbage collection), wi(cid:218)c podczas stosowania referencji nie ma po- trzeby zbytniego przejmowania si(cid:218) zwalnianiem alokowanej pami(cid:218)ci. 22 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę Dobrym zwyczajem jest jednak dereferencja obiektów, które nie b(cid:218)d(cid:200) ju(cid:285) u(cid:285)ywane, tak aby od(cid:258)miecacz móg(cid:239) zwolni(cid:202) zajmowan(cid:200) przez nie pami(cid:218)(cid:202). Aby to zrobi(cid:202), wystarczy zmiennej referencyjnej przypisa(cid:202) null: var object1 = new Object(); // jakie(cid:286) operacje na obiekcie object1 = null; // dereferencja Obiekt object1 jest tworzony, nast(cid:218)pnie u(cid:285)ywany, a na ko(cid:241)cu zmien- nej jest przypisywany null. Je(cid:258)li nie istniej(cid:200) (cid:285)adne inne referencje do tego obiektu, od(cid:258)miecacz mo(cid:285)e zwolni(cid:202) zajmowan(cid:200) przez niego pami(cid:218)(cid:202). (cid:165)wiadome wykorzystanie tego mechanizmu jest szczególnie istotne w du- (cid:285)ych aplikacjach, w których jest tworzonych bardzo du(cid:285)o obiektów. Dodawanie i usuwanie w(cid:239)a(cid:258)ciwo(cid:258)ci Bardzo ciekaw(cid:200) cech(cid:200) obiektów w JavaScripcie jest mo(cid:285)liwo(cid:258)(cid:202) dodawa- nia i usuwania w(cid:239)a(cid:258)ciwo(cid:258)ci w dowolnym momencie. Oto przyk(cid:239)ad: var object1 = new Object(); var object2 = object1; object1.myCustomProperty = Super! ; console.log(object2.myCustomProperty); // Super! Do obiektu object1 zostaje dodana w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) myCustomProperty o war- to(cid:258)ci Super! . Do w(cid:239)a(cid:258)ciwo(cid:258)ci tej mo(cid:285)na si(cid:218) odwo(cid:239)a(cid:202) równie(cid:285) przez obiekt object2, poniewa(cid:285) obie zmienne (object1 i object2) wskazuj(cid:200) t(cid:218) sam(cid:200) instancj(cid:218). UWAGA Ten przyk(cid:239)ad ilustruje jedn(cid:200) z ciekawszych cech j(cid:218)zyka Java- Script — mo(cid:285)liwo(cid:258)(cid:202) modyfikowania obiektów w dowolnym momen- cie, nawet je(cid:258)li wcze(cid:258)niej nie zosta(cid:239)y w ogóle zdefiniowane. W sytu- acjach gdy taka mo(cid:285)liwo(cid:258)(cid:202) jest niepo(cid:285)(cid:200)dana, mo(cid:285)na temu zapobiega(cid:202) na kilka sposobów (poznasz je w dalszej cz(cid:218)(cid:258)ci ksi(cid:200)(cid:285)ki). Poza podstawowym, ogólnym typem referencyjnym JavaScript ofe- ruje kilka innych, bardzo przydatnych, wbudowanych typów. T y p y p r o s t e i r e fe r e n c j e 23 Kup książkęPoleć książkę Tworzenie instancji wbudowanych typów Wcze(cid:258)niej omówili(cid:258)my sposób tworzenia ogólnych obiektów za pomoc(cid:200) operatora new i konstruktora: new Object(). Typ Object jest tylko jednym z kilku przydatnych wbudowanych typów referencyjnych dost(cid:218)pnych w j(cid:218)zyku JavaScript. Pozosta(cid:239)e s(cid:200) bardziej wyspecjalizowane. Poni(cid:285)ej znajduje si(cid:218) krótki opis wbudowanych typów: Array Date Error tablica indeksowana numerycznie data i czas b(cid:239)(cid:200)d w czasie wykonania (istniej(cid:200) równie(cid:285) bardziej konkretne podtypy b(cid:239)(cid:218)dów) Function funkcja Object RegExp ogólny obiekt wyra(cid:285)enie regularne Instancje wbudowanych typów mo(cid:285)na tworzy(cid:202) za pomoc(cid:200) operatora new, co wida(cid:202) w poni(cid:285)szym przyk(cid:239)adzie: var items = new Array(); var now = new Date(); var error = new Error( Sta(cid:239)o si(cid:218) co(cid:258) z(cid:239)ego. ); var func = new Function( console.log( Cze(cid:258)(cid:202) ); ); var object = new Object(); var re = new RegExp( \\d+ ); Litera(cid:239)y Niektóre wbudowane typy s(cid:200) dost(cid:218)pne w formie litera(cid:239)ów. Litera(cid:239) to sk(cid:239)adnia umo(cid:285)liwiaj(cid:200)ca zdefiniowanie typu referencyjnego bez potrzeby jawnego tworzenia obiektu za pomoc(cid:200) operatora new i konstruktora. We wcze(cid:258)niejszych przyk(cid:239)adach z tego rozdzia(cid:239)u by(cid:239)y stosowane litera(cid:239)y warto(cid:258)ci prostych, czyli litera(cid:239)y (cid:239)a(cid:241)cuchów, liczb, warto(cid:258)ci logicznych, a tak(cid:285)e litera(cid:239)y null i undefined. 24 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę Litera(cid:239)y obiektów i tablic Aby utworzy(cid:202) obiekt za pomoc(cid:200) litera(cid:239)u obiektu, wystarczy zdefiniowa(cid:202) w(cid:239)a(cid:258)ciwo(cid:258)ci wewn(cid:200)trz nawiasów klamrowych. Ka(cid:285)da w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) jest zbu- dowana z nazwy ((cid:239)a(cid:241)cucha), dwukropka i warto(cid:258)ci. Poszczególne w(cid:239)a(cid:258)ci- wo(cid:258)ci rozdziela si(cid:218) przecinkami: var book = { name: JavaScript. Programowanie obiektowe , year: 2014 }; Nazwa w(cid:239)a(cid:258)ciwo(cid:258)ci mo(cid:285)e by(cid:202) równie(cid:285) litera(cid:239)em (cid:239)a(cid:241)cucha, co bywa przy- datne w przypadku nazw zawieraj(cid:200)cych spacje lub inne znaki specjalne: var book = { name : JavaScript. Programowanie obiektowe , year : 2014 }; Pomijaj(cid:200)c ró(cid:285)nic(cid:218) w sk(cid:239)adni, ten przyk(cid:239)ad jest równowa(cid:285)ny poprzed- niemu. Ten sam efekt mo(cid:285)na uzyska(cid:202) w jeszcze inny sposób: var book = new Object(); book.name = JavaScript. Programowanie obiektowe ; book.year = 2014; Wynik dzia(cid:239)ania wszystkich trzech przedstawionych fragmentów ko- du jest taki sam — powstaje obiekt z dwiema w(cid:239)a(cid:258)ciwo(cid:258)ciami. Mo(cid:285)na wi(cid:218)c korzysta(cid:202) z dowolnego zapisu, poniewa(cid:285) funkcjonalnie s(cid:200) one do- k(cid:239)adnie takie same. UWAGA U(cid:285)ycie litera(cid:239)u obiektu nie wi(cid:200)(cid:285)e si(cid:218) tak naprawd(cid:218) z wywo(cid:239)a- niem konstruktora new Object(). Silnik JavaScriptu wykonuje jednak te same operacje co w przypadku tego wywo(cid:239)ania. Odnosi si(cid:218) to do wszystkich litera(cid:239)ów typów referencyjnych. W podobny sposób stosuje si(cid:218) litera(cid:239) tablicy: dowoln(cid:200) liczb(cid:218) warto(cid:258)ci rozdzielonych przecinkami umieszcza si(cid:218) w nawiasach kwadratowych: T y p y p r o s t e i r e fe r e n c j e 25 Kup książkęPoleć książkę var colors = [ czerwony , niebieski , zielony ]; console.log(colors[0]); // czerwony Taki zapis daje ten sam efekt co poni(cid:285)szy kod: var colors = new Array( czerwony , niebieski , zielony ); console.log(colors[0]); // czerwony Litera(cid:239)y funkcji W wi(cid:218)kszo(cid:258)ci przypadków funkcje definiuje si(cid:218) za pomoc(cid:200) litera(cid:239)ów. Tak naprawd(cid:218) konstruktor Function jest stosowany w specyficznych sytu- acjach — gdy cia(cid:239)o funkcji jest zapisane jako (cid:239)a(cid:241)cuch. Taki kod jest trud- ny w utrzymaniu, analizowaniu i debugowaniu, wi(cid:218)c raczej nie spotkasz si(cid:218) z nim w praktyce. Tworzenie funkcji za pomoc(cid:200) litera(cid:239)u jest o wiele prostsze i niesie za sob(cid:200) mniejsze ryzyko pope(cid:239)nienia b(cid:239)(cid:218)du. Oto przyk(cid:239)ad: function reflect(value) { return value; } // jest równowa(cid:298)ne temu: var reflect = new Function( value , return value; ); W powy(cid:285)szym kodzie jest definiowana funkcja reflect(), która zwra- ca przekazan(cid:200) do niej warto(cid:258)(cid:202). Nawet w przypadku tak prostej funkcji mo(cid:285)na zauwa(cid:285)y(cid:202), (cid:285)e posta(cid:202) litera(cid:239)u jest o wiele prostsza w czytaniu i zro- zumieniu ni(cid:285) wersja z konstruktorem. Trzeba te(cid:285) pami(cid:218)ta(cid:202), (cid:285)e nie ma dobrego sposobu na debugowanie funkcji utworzonych za pomoc(cid:200) kon- struktora, poniewa(cid:285) takie funkcje nie s(cid:200) rozpoznawane przez debugery JavaScriptu. W aplikacji s(cid:200) wi(cid:218)c czarnymi skrzynkami — wiemy tylko, co do nich jest przekazywane i co zwracaj(cid:200). Litera(cid:239)y wyra(cid:285)e(cid:241) regularnych JavaScript oferuje równie(cid:285) litera(cid:239)y wyra(cid:285)e(cid:241) regularnych, dzi(cid:218)ki którym mo(cid:285)na definiowa(cid:202) wyra(cid:285)enia regularne bez konieczno(cid:258)ci u(cid:285)ycia kon- struktora RegExp. S(cid:200) one zapisywane podobnie jak w j(cid:218)zyku Perl: wzorzec 26 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę jest zapisywany mi(cid:218)dzy prawymi uko(cid:258)nikami, a ewentualne opcje umiesz- cza si(cid:218) za uko(cid:258)nikiem zamykaj(cid:200)cym: var numbers = /\d+/g; // jest równowa(cid:298)ne temu: var numbers = new RegExp( \\d+ , g ); Z litera(cid:239)ów wyra(cid:285)e(cid:241) regularnych korzysta si(cid:218) troch(cid:218) pro(cid:258)ciej ni(cid:285) z kon- struktora, poniewa(cid:285) nie trzeba stosowa(cid:202) znaków ucieczki (tzw. escaping). Kiedy u(cid:285)ywa si(cid:218) konstruktora, wyra(cid:285)enie regularne przekazuje si(cid:218) jako (cid:239)a(cid:241)cuch, wi(cid:218)c wszystkie znaki lewych uko(cid:258)ników trzeba poprzedzi(cid:202) do- datkowym lewym uko(cid:258)nikiem (w(cid:239)a(cid:258)nie dlatego w powy(cid:285)szym przyk(cid:239)adzie w wersji z litera(cid:239)em jest \d, a w wersji z konstruktorem — \\d). Z tego wzgl(cid:218)du lepiej stosowa(cid:202) litera(cid:239)y, z wyj(cid:200)tkiem sytuacji gdy wyra(cid:285)enie re- gularne jest konstruowane dynamicznie. Podsumowuj(cid:200)c, poza przypadkiem konstruktora Function tak na- prawd(cid:218) nie ma wi(cid:218)kszego znaczenia sposób tworzenia instancji wbudo- wanych typów. Niektórzy programi(cid:258)ci preferuj(cid:200) litera(cid:239)y, a inni konstruktory. Stosuj wi(cid:218)c takie rozwi(cid:200)zanie, które w danej sytuacji wydaje si(cid:218) wygod- niejsze i lepsze. Dost(cid:218)p do w(cid:239)a(cid:258)ciwo(cid:258)ci Jak ju(cid:285) zosta(cid:239)o wspomniane, w(cid:239)a(cid:258)ciwo(cid:258)ci to pary nazwa-warto(cid:258)(cid:202) zapisane w obiekcie. W JavaScripcie, podobnie jak w wielu innych j(cid:218)zykach, w celu uzyskania dost(cid:218)pu do w(cid:239)a(cid:258)ciwo(cid:258)ci najcz(cid:218)(cid:258)ciej stosuje si(cid:218) notacj(cid:218) z kropk(cid:200). Mo(cid:285)na jednak zastosowa(cid:202) zapis z nawiasami klamrowymi, mi(cid:218)dzy któ- rymi umieszcza si(cid:218) nazw(cid:218) w(cid:239)a(cid:258)ciwo(cid:258)ci. Jako przyk(cid:239)ad pos(cid:239)u(cid:285)y prosty kod, w którym zosta(cid:239) zastosowany zapis z kropk(cid:200): var array = []; array.push(12345); Mo(cid:285)na to zapisa(cid:202) inaczej, umieszczaj(cid:200)c nazw(cid:218) metody (jako (cid:239)a(cid:241)cuch) w nawiasach kwadratowych: T y p y p r o s t e i r e fe r e n c j e 27 Kup książkęPoleć książkę var array = []; array[ push ](12345); Taki zapis przydaje si(cid:218) w sytuacjach, gdy musimy dynamicznie decy- dowa(cid:202), do której w(cid:239)a(cid:258)ciwo(cid:258)ci chcemy uzyska(cid:202) dost(cid:218)p. Zamiast korzysta(cid:202) z litera(cid:239)u (cid:239)a(cid:241)cucha, nazw(cid:218) po(cid:285)(cid:200)danej w(cid:239)a(cid:258)ciwo(cid:258)ci mo(cid:285)na zapisa(cid:202) w zmiennej i przekaza(cid:202) j(cid:200) w nawiasach klamrowych: var array = []; var method = push ; array[method](12345); Zmienna method ma warto(cid:258)(cid:202) push , wi(cid:218)c na tablicy (zmiennej array) jest wywo(cid:239)ywana metoda push(). Ta przydatna mo(cid:285)liwo(cid:258)(cid:202) zostanie wyko- rzystana jeszcze kilkukrotnie w dalszej cz(cid:218)(cid:258)ci ksi(cid:200)(cid:285)ki. Je(cid:258)li pominiemy sk(cid:239)adni(cid:218) czy wydajno(cid:258)(cid:202), zauwa(cid:285)ymy, (cid:285)e jedyna ró(cid:285)nica mi(cid:218)dzy zapisem z kropk(cid:200) i nawiasami polega na tym, (cid:285)e drugi sposób daje mo(cid:285)liwo(cid:258)(cid:202) za- stosowania w nazwach w(cid:239)a(cid:258)ciwo(cid:258)ci znaków specjalnych, co czasem mo(cid:285)e si(cid:218) przyda(cid:202). Programi(cid:258)ci preferuj(cid:200) zapis z kropk(cid:200), poniewa(cid:285) taki kod (cid:239)atwiej si(cid:218) czyta i analizuje. Identyfikowanie typów referencyjnych Najprostszym do zidentyfikowania typem referencyjnym jest funkcja, poniewa(cid:285) operator typeof zwraca (cid:239)a(cid:241)cuch function : function reflect(value) { return value; } console.log(typeof reflect); // function Pozosta(cid:239)e typy referencyjne trudniej okre(cid:258)li(cid:202), poniewa(cid:285) operator typeof zwraca dla nich wszystkich (cid:239)a(cid:241)cuch object . Mo(cid:285)e si(cid:218) to okaza(cid:202) pro- blemem, je(cid:258)li korzysta si(cid:218) z wielu ró(cid:285)nych typów. W takich sytuacjach z pomoc(cid:200) przychodzi inny operator j(cid:218)zyka JavaScript — instanceof. 28 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę Operator ten ma dwa parametry: obiekt i konstruktor. Je(cid:258)li obiekt jest in- stancj(cid:200) typu okre(cid:258)lonego przez konstruktor, operator zwraca true, a w prze- ciwnych przypadku — false. Oto przyk(cid:239)ad: var items = []; var object = {}; function reflect(value) { return value; } console.log(items instanceof Array); // true console.log(object instanceof Object); // true console.log(reflect instanceof Function); // true W powy(cid:285)szym kodzie za pomoc(cid:200) operatora instanceof jest testowa- nych kilka warto(cid:258)ci. Wszystkie zosta(cid:239)y prawid(cid:239)owo zidentyfikowane jako instancje typów okre(cid:258)lonych przez podane konstruktory (mimo (cid:285)e obiekty by(cid:239)y tworzone za pomoc(cid:200) litera(cid:239)ów). Operator instanceof poprawnie identyfikuje równie(cid:285) typy dziedzi- czone po innych typach. Ze wzgl(cid:218)du na to, (cid:285)e wszystkie typy wbudowa- ne dziedzicz(cid:200) po Object, ka(cid:285)dy obiekt b(cid:218)dzie rozpoznany jako instancja typu Object. Dobrze to ilustruje poni(cid:285)szy przyk(cid:239)ad, w którym pod tym k(cid:200)tem s(cid:200) sprawdzane wcze(cid:258)niej utworzone obiekty: var items = []; var object = {}; function reflect(value) { return value; } console.log(items instanceof Array); // true console.log(items instanceof Object); // true console.log(object instanceof Object); // true console.log(object instanceof Array); // false console.log(reflect instanceof Function); // true console.log(reflect instanceof Object); // true T y p y p r o s t e i r e fe r e n c j e 29 Kup książkęPoleć książkę Wszystkie obiekty typów wbudowanych zosta(cid:239)y rozpoznane jako in- stancje typu Object, poniewa(cid:285) po nim dziedzicz(cid:200). Identyfikowanie tablic Mimo (cid:285)e operator instanceof prawid(cid:239)owo rozpoznaje tablice, jest jeden wyj(cid:200)tek, gdy sobie nie radzi. W aplikacjach webowych mo(cid:285)e doj(cid:258)(cid:202) do sytuacji, gdy warto(cid:258)ci s(cid:200) wymieniane mi(cid:218)dzy ramkami w obr(cid:218)bie tej samej strony internetowej. Problem polega na tym, (cid:285)e ka(cid:285)da ramka ma swój w(cid:239)asny globalny kontekst, a wi(cid:218)c w(cid:239)asne wersje Object, Array i pozosta- (cid:239)ych typów wbudowanych. Je(cid:258)li przeka(cid:285)e si(cid:218) tablic(cid:218) z jednej ramki do drugiej, operator instanceof nie zadzia(cid:239)a prawid(cid:239)owo, poniewa(cid:285) ta tabli- ca jest instancj(cid:200) typu Array z innej ramki. Problem ten rozwi(cid:200)zuje wprowadzona w ECMAScript 5 metoda Array.isArray(), która jednoznacznie okre(cid:258)la, czy przekazana jej warto(cid:258)(cid:202) jest tablic(cid:200), czy nie. Metoda ta zwraca true, je(cid:258)li przeka(cid:285)e si(cid:218) jej natywn(cid:200) tablic(cid:218), niezale(cid:285)nie od kontekstu, z którego pochodzi. Jest to najlepszy sposób na identyfikowanie tablic: var items = []; console.log(Array.isArray(items)); // true Metod(cid:218) Array.isArray() mo(cid:285)na stosowa(cid:202) w (cid:258)rodowiskach zgodnych z ECMAScript 5, a wi(cid:218)c w zdecydowanej wi(cid:218)kszo(cid:258)ci przegl(cid:200)darek (In- ternet Explorer obs(cid:239)uguje j(cid:200) od wersji 9.) i w (cid:258)rodowisku Node.js. Typy opakowuj(cid:200)ce W j(cid:218)zyku JavaScript spore zamieszanie mo(cid:285)e wprowadza(cid:202) koncepcja typów opakowuj(cid:200)cych typy proste (ang. primitive wrapper types). Istniej(cid:200) trzy takie typy: String, Number i Boolean. S(cid:200) to typy referencyjne, dzi(cid:218)ki któ- rym warto(cid:258)ciami typów prostych mo(cid:285)na si(cid:218) pos(cid:239)ugiwa(cid:202) jak obiektami, co okazuje si(cid:218) bardzo przydatne. Wystarczy sobie wyobrazi(cid:202) ba(cid:239)agan w ko- dzie spowodowany konieczno(cid:258)ci(cid:200) zastosowania innej sk(cid:239)adni lub przej- (cid:258)cia na styl programowania proceduralnego z powodu, na przyk(cid:239)ad, po- trzeby wyznaczenia pod(cid:239)a(cid:241)cucha z jakiej(cid:258) zmiennej tekstowej. 30 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę Typy opakowuj(cid:200)ce s(cid:200) automatycznie tworzone, w chwili gdy odczy- tywana jest warto(cid:258)(cid:202) typu prostego string, number lub boolean. Przeanali- zujmy prosty przyk(cid:239)ad. W pierwszym wierszu poni(cid:285)szego fragmentu kodu zmiennej name jest przypisywany (cid:239)a(cid:241)cuch typu prostego (string). W dru- gim wierszu traktujemy t(cid:218) zmienn(cid:200) jak obiekt — wywo(cid:239)ujemy na niej metod(cid:218) charAt(0) z zastosowaniem notacji z kropk(cid:200). var name = Nicholas ; var firstChar = name.charAt(0); console.log(firstChar); // N Aby zobrazowa(cid:202), co si(cid:218) dzieje w tym kodzie poza nasz(cid:200) wiedz(cid:200), trze- ba go uzupe(cid:239)ni(cid:202) o kilka dodatkowych operacji: // silnik JavaScriptu wykonuje takie operacje var name = Nicholas ; var temp = new String(name); var firstChar = temp.charAt(0); temp = null; console.log(firstChar); // N Poniewa(cid:285) potraktowali(cid:258)my zmienn(cid:200) typu prostego jak obiekt, silnik JavaScriptu utworzy(cid:239) instancj(cid:218) typu String, tak by da(cid:239)o si(cid:218) wywo(cid:239)a(cid:202) metod(cid:218) charAt(0). Obiekt typu String istnieje tylko na potrzeby tej jed- nej operacji (proces ten okre(cid:258)la si(cid:218) terminem autoboxing). (cid:146)atwo to sprawdzi(cid:202) — wystarczy doda(cid:202) do zmiennej name jak(cid:200)(cid:258) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) (trak- tuj(cid:200)c t(cid:218) zmienn(cid:200) jak zwyk(cid:239)y obiekt): var name = Nicholas ; name.last = Zakas ; console.log(name.last); // undefined W tym kodzie do (cid:239)a(cid:241)cucha name staramy si(cid:218) doda(cid:202) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) last. Kod wydaje si(cid:218) prawid(cid:239)owy, ale wynik jego dzia(cid:239)ania ju(cid:285) nie. Co si(cid:218) dzieje? Gdy pracujemy z obiektami, mo(cid:285)emy dodawa(cid:202) do nich nowe w(cid:239)a(cid:258)ciwo(cid:258)ci, kiedy tylko chcemy, a co wa(cid:285)ne, pozostaj(cid:200) one w obiekcie a(cid:285) do chwili ich usuni(cid:218)cia. W przypadku typów opakowuj(cid:200)cych jest inaczej, poniewa(cid:285) automatycznie tworzone obiekty s(cid:200) praktycznie od razu niszczone. T y p y p r o s t e i r e fe r e n c j e 31 Kup książkęPoleć książkę Powy(cid:285)szy fragment kodu zostanie uzupe(cid:239)niony przez silnik Java- Scriptu w nast(cid:218)puj(cid:200)cy sposób: // silnik JavaScriptu wykonuje takie operacje var name = Nicholas ; var temp = new String(name); temp.last = Zakas ; temp = null; // tymczasowy obiekt zostaje zniszczony var temp = new String(name); console.log(temp.last); // undefined temp = null; Nowa w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) nie jest przypisywana do (cid:239)a(cid:241)cucha, ale do tymcza- sowego obiektu, który jest od razu niszczony. Kiedy w dalszej cz(cid:218)(cid:258)ci ko- du chcemy odczyta(cid:202) t(cid:218) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), znów jest tworzony tymczasowy obiekt, który oczywi(cid:258)cie jej nie posiada. Je(cid:285)eli na zmiennej typu prostego zastosujemy operator instanceof, uzyskamy wynik false, mimo (cid:285)e — jak widzieli(cid:258)my — referencje s(cid:200) two- rzone automatycznie: var name = Nicholas ; var count = 10; var found = false; console.log(name instanceof String); // false console.log(count instanceof Number); // false console.log(found instanceof Boolean); // false Dzieje si(cid:218) tak dlatego, (cid:285)e tymczasowe obiekty s(cid:200) tworzone tylko w sytu- acji, gdy odczytywana jest warto(cid:258)(cid:202) zmiennej. Operator instanceof nicze- go nie odczytuje, wi(cid:218)c nie jest tworzony tymczasowy obiekt, w zwi(cid:200)zku z czym zmienna nie jest instancj(cid:200) typu opakowuj(cid:200)cego. Obiekt opako- wuj(cid:200)cy mo(cid:285)na utworzy(cid:202) jawnie, ale ma to pewne efekty uboczne: var name = new String( Nicholas ); var count = new Number(10); var found = new Boolean(false); 32 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę console.log(typeof name); // object console.log(typeof count); // object console.log(typeof found); // object Jak wida(cid:202), tworzymy w ten sposób ogólne obiekty, wi(cid:218)c operator typeof nie mo(cid:285)e zidentyfikowa(cid:202) faktycznego typu przechowywanych w nich danych. Trzeba te(cid:285) wiedzie(cid:202), (cid:285)e w wielu sytuacjach instancje typów String, Number i Boolean zachowuj(cid:200) si(cid:218) inaczej ni(cid:285) ich proste odpowiedniki. W poni(cid:285)szym fragmencie kodu korzystamy z obiektu Boolean o warto(cid:258)ci false. Po uruchomieniu kodu w konsoli zostanie jednak wy(cid:258)wietlony komu- nikat Znaleziony , poniewa(cid:285) w instrukcji warunkowej obiekt jest zawsze traktowany jak warto(cid:258)(cid:202) true. Nie jest wi(cid:218)c istotne, (cid:285)e ten obiekt opako- wuje warto(cid:258)(cid:202) false — jest obiektem, wi(cid:218)c w tej sytuacji jest traktowany jako true. var found = new Boolean(false); if (found) { console.log( Znaleziony ); // to zostanie wykonane } R(cid:218)czne tworzenie instancji typów opakowuj(cid:200)cych mo(cid:285)e wprowadza(cid:202) zamieszanie, wi(cid:218)c lepiej tego unika(cid:202), chyba (cid:285)e ma si(cid:218) wyra(cid:283)ny powód. Korzystanie z obiektów opakowuj(cid:200)cych zamiast prostych warto(cid:258)ci pro- wadzi najcz(cid:218)(cid:258)ciej do trudnych do wykrycia b(cid:239)(cid:218)dów. Podsumowanie Mimo (cid:285)e w j(cid:218)zyku JavaScript nie ma klas, s(cid:200) typy. Wszystkie zmienne i fragmenty danych s(cid:200) powi(cid:200)zane z okre(cid:258)lonymi warto(cid:258)ciami typu pro- stego lub referencjami. Pi(cid:218)(cid:202) typów prostych ((cid:239)a(cid:241)cuchy, liczby, warto(cid:258)ci logiczne, null i undefined) reprezentuje warto(cid:258)ci zapisywane bezpo(cid:258)red- nio w obiekcie zmiennych dla danego kontekstu. Do identyfikowania tych typów mo(cid:285)na u(cid:285)y(cid:202) operatora typeof. Wyj(cid:200)tkiem jest null, który mo(cid:285)na wykry(cid:202) tylko przez bezpo(cid:258)rednie porównanie z warto(cid:258)ci(cid:200) null. Typy referencyjne w JavaScripcie najbli(cid:285)ej odpowiadaj(cid:200) klasom znanym z innych j(cid:218)zyków. Obiekty s(cid:200) instancjami klas referencyjnych. Nowe obiekty mo(cid:285)na tworzy(cid:202) za pomoc(cid:200) operatora new lub litera(cid:239)u referencji. T y p y p r o s t e i r e fe r e n c j e 33 Kup książkęPoleć książkę Dost(cid:218)p do w(cid:239)a(cid:258)ciwo(cid:258)ci i metod jest realizowany przede wszystkim za pomo- c(cid:200) notacji z kropk(cid:200), ale mo(cid:285)na te(cid:285) korzysta(cid:202) z notacji z nawiasami kwa- dratowymi. Funkcje s(cid:200) w JavaScripcie obiektami i mo(cid:285)na je identyfiko- wa(cid:202) za pomoc(cid:200) operatora typeof. Aby sprawdzi(cid:202), czy obiekt jest instancj(cid:200) okre(cid:258)lonego typu referencyjnego, nale(cid:285)y u(cid:285)y(cid:202) operatora instanceof. Dzi(cid:218)ki trzem typom opakowuj(cid:200)cym — String, Number i Boolean — zmienne typów prostych mo(cid:285)na traktowa(cid:202) jak referencje. Silnik Java- Scriptu automatycznie tworzy obiekty opakowuj(cid:200)ce, wi(cid:218)c z poziomu ko- du prostymi zmiennymi mo(cid:285)na si(cid:218) pos(cid:239)ugiwa(cid:202) jak obiektami, ale trzeba pami(cid:218)ta(cid:202), (cid:285)e obiekty te s(cid:200) tymczasowe, wi(cid:218)c s(cid:200) niszczone zaraz po ich u(cid:285)yciu. Mimo (cid:285)e instancje typów opakowuj(cid:200)cych mo(cid:285)na tworzy(cid:202) samo- dzielnie, nie jest to zalecane ze wzgl(cid:218)du na wprowadzanie zamieszania i wi(cid:218)ksze prawdopodobie(cid:241)stwo pope(cid:239)nienia pomy(cid:239)ki. 34 R o z d z i a(cid:239) 1 Kup książkęPoleć książkę A aggregation, Patrz: agregacja agregacja, 12 arity, Patrz: funkcja arno(cid:258)(cid:202) b(cid:239)(cid:200)d, 24 B C closure, Patrz: domkni(cid:218)cie constructor stealing, Patrz: konstruktor zaw(cid:239)aszczanie czas, 24 D dane referencja, Patrz: referencja typ prosty, Patrz: typ prosty w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) danych data, 24 dereferencja, 23 domieszka, 107, 113, 116 domkni(cid:218)cie, 109 dostawca, 113 Skorowidz dziedziczenie, 12 konstruktorów, 99 obiektów, 96 prototypowe, 91 pseudoklasyczne, 104, 115 E ECMAScript 5, 35, 47, 60, 119 encapsulation, Patrz: kapsu(cid:239)kowanie enumerable, Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) wyliczalna F funkcja, 12, 16, 21, 24, 28, 35, 37 anonimowa, 39 argumentowo(cid:258)(cid:202), Patrz: funkcja arno(cid:258)(cid:202) arno(cid:258)(cid:202), 40 deklaracja, 36, 37 dost(cid:218)powa, 58, 59, 65, 66, 77, 118 w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) funkcji dost(cid:218)powej odczytuj(cid:200)ca, 58, 59, 64 parametr, 39, 40 porównuj(cid:200)ca, 38 przeci(cid:200)(cid:285)anie, 41 reflect, 26 Kup książkęPoleć książkę funkcja sygnatura, 41 w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), 40, 58, 64 zapisuj(cid:200)ca, 58, 60, 64, 66 G garbage collection, Patrz: mechanizm od(cid:258)miecania pami(cid:218)ci generic, Patrz: obiekt ogólny getter, Patrz: funkcja odczytuj(cid:200)ca hoisting, 36 H I IIFE, Patrz: wyra(cid:285)enie funkcji natychmiastowej immediately invoked function expression, Patrz: wyra(cid:285)enie funkcji natychmiastowej inheritance, Patrz: dziedziczenie instrukcja for-in, 113 interfejs implementacja, 12 J j(cid:218)zyk bazuj(cid:200)cy na klasach, 15 bazuj(cid:200)cy na obiektach, 16 obiektowy, 11, 12, 16 K kapsu(cid:239)kowanie, 12 klasa, 11, 12, 15 konstruktor, 73 Array, 120, 121 bezparametrowy, 74 dziedziczenie, 99 Error, 121 Function, 26 litera(cid:239), 75 124 S k o r o w i d z nazwa, 21 new Object, 21, 23, 24 Object, 21, 51, 121 RegExp, 26, 120, 121 tworzenie, 74 wywo(cid:239)ywanie, 77 z prywatn(cid:200) w(cid:239)a(cid:258)ciwo(cid:258)ci(cid:200), 111 zasi(cid:218)g, 120 zaw(cid:239)aszczanie, 103 zwracanie warto(cid:258)ci, 76 L litera(cid:239), 17, 24 konstruktora, 75 liczby, 24 (cid:239)a(cid:241)cucha, 24 null, 24 obiektu, 25, 51, 75 undefined, 24 warto(cid:258)ci logicznej, 24 wyra(cid:285)enia regularnego, 26 M mechanizm od(cid:258)miecania pami(cid:218)ci, 22 przenoszenia deklaracji na pocz(cid:200)tek, 37 rzutowania, 53 metoda, 13, 21, 43 add, 95 apply, 46, 103 Array.isArray, 30 bind, 47 call, 45, 103 Delete, 55 hasOwnProperty, 55, 78, 92 isPrototypeOf, 92 Object.create, 96 Object.defineProperties, 66 Object.defineProperty, 60, 62, 63, 64, 65, 117, 119 Object.freeze, 70 Kup książkęPoleć książkę Object.getOwnPropertyDescriptor, 67, 119 Object.getOwnPropertyNames, 119 Object.isSealed, 69 Object.keys, 57, 119 Object.preventExtensions, 68 propertyIsEnumerable, 57, 61, 92 przes(cid:239)oni(cid:218)ta, 104 Put, 52, 53, 58 Set, 52 sort, 38 toString, 55, 81, 92, 93 typów prostych, 20 uprzywilejowana, 108 valueOf, 92, 93 wspó(cid:239)dzielenie, 78 mixin, Patrz: domieszka module pattern, Patrz: wzorzec modu(cid:239)u N Node.js, 13 notacja z kropk(cid:200), 12, 27 O obiekt, 12, 22, 51, 92 arguments, 39, 40 atrybut Extensible, 68 bez w(cid:239)a(cid:258)ciwo(cid:258)ci, 81 dereferencja, Patrz: dereferencja dziedziczenie, 96 litera(cid:239), Patrz: litera(cid:239) obiektu modyfikowanie, 23 nierozszerzalny, 68, 69, 70 ogólny, 75 piecz(cid:218)towanie, 69, 87 rozszerzalny, 68 this, 44, 45, 46, 47 tworzenie, 51 wbudowany, 88, 89 w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) obiektu wzorzec, 107 zamro(cid:285)ony, 70, 87 zdarzenie, 113, 115 zmiennych, 16 odbiorca, 113, 117 operator, 93 ==, 20 ===, 20 delete, 55, 81 in, 54, 55 instanceof, 28, 30, 74, 75 new, 22, 24, 74, 120 typeof, 19, 35 own property, Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) w(cid:239)asna P pakiet, 15 p(cid:218)tla for-in, 56, 57 plik nag(cid:239)ówkowy, 12 polimorfizm, 12 primitive, Patrz: typ prosty primitive wrapper types, Patrz: typ opakowuj(cid:200)cy typ prosty privilaged method, Patrz: metoda uprzywilejowana programowanie obiektowe, 13 prototyp, 78 (cid:239)a(cid:241)cuchowanie, 91, 103, 113 modyfikowanie, 86 obiektu wbudowanego, 88, 89 Object.prototype, 92, 94 Person.prototype, 117 w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), Patrz: w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) prototypu prototypal inheritance, Patrz: dziedziczenie prototypowe prototype chaining, Patrz: prototyp (cid:239)a(cid:241)cuchowanie pseudoclassical inheritance, Patrz: dziedziczenie pseudoklasyczne pseudodziedziczenie oparte na domieszkach, 113 S k o r o w i d z 125 Kup książkęPoleć książkę R receiver, Patrz: odbiorca redundancja, 78 referencja, 12, 16, 21, 22, 28, 45, 93 wyra(cid:285)enie, 24 revealing module pattern, Patrz: wzorzec modu(cid:239)u z ujawnianiem S setter, Patrz:(cid:3)funkcja zapisuj(cid:268)ca s(cid:239)owo kluczowe function, 36 get, 59 set, 59 sterta, 16 stos, 16 supplier, Patrz: dostawca T tablica tryb typ asocjacyjna klucz, 52 klucz-warto(cid:258)(cid:202), 55 indeksowana numerycznie, 24 standardowy, 120 (cid:258)cis(cid:239)y, 62, 63, 66, 69, 71, 77, 120 zwyk(cid:239)y, 62, 64, 66, 69 opakowuj(cid:200)cy, 88, 93 Boolean, 30 Number, 30 String, 30 typ prosty, 30 prosty, 16, 17, 21, 93 Boolean, 17, 31, 93 Date, 93 identyfikowanie, 19 metoda, Patrz: metoda typów prostych null, 17, 19 126 S k o r o w i d z Number, 17, 31, 93 String, 17, 20, 31, 93 undefined, 17 referencyjny, Patrz: referencja wbudowany, 24 Array, 24 Date, 24 Error, 24 Function, 24 instancja, 24 Object, 24 RegExp, 24 typowanie s(cid:239)abe, 13 W warto(cid:258)(cid:202) this, 45, 46, 47, 120 weak typing, Patrz: typowanie s(cid:239)abe w(cid:239)a(cid:258)ciwo(cid:258)(cid:202), 16, 21, 27, 35 atrybut, 62, 63 Configurable, 60, 61, 65, 69 Enumerable, 56, 60, 61, 65 Extensible, 69 Get, 64 odczytywanie, 67 Set, 64 Value, 62, 64 Writable, 62, 64 zmiana, 60 Call, 35 constructor, 75, 84 danych, 58 deskryptor, 61, 96 dodana, 54 dodawanie, 23, 66 funkcji dost(cid:218)powej, 58, 59, 64 instancji, 57, 60 konfigurowalna, 60 length, 39, 40 lista, 57 name, 63 obiektu, 52, 68, 69 Prototype, 52, 54, 55, 57, 78, 79, 92, 99 Kup książkęPoleć książkę prywatna, 111 usuwanie, 23, 55 w(cid:239)asna, 54 wyliczalna, 56, 57, 60, 119 wska(cid:283)nik, 22 wyra(cid:285)enie funkcji natychmiastowej, 108 funkcyjne, 36, 37 regularne, 26 konstruowane dynamicznie, 27 rozpoznawane jako funkcja, 35 wzorzec modu(cid:239)u, 108, 110 obiektu, Patrz: obiekt wzorzec Z zdarzenie, 113, 115 zmienna referencyjna, 23 znak ==, 20 ===, 20 ucieczki, 27 S k o r o w i d z 127 Kup książkęPoleć książkę 128 S k o r o w i d z Kup książkęPoleć książkę
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

JavaScript. Zasady programowania obiektowego
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: