Este un moment excelent pentru JavaScript. Nu numai că devine un limbaj mult mai respectat, dar crește și în salturi - atât în popularitate, cât și în trăsături. Pe măsură ce mai multe browsere încep să implementeze caracteristicile standardului ECMAScript ediția a 5-a, JavaScript devine o platformă și mai puternică pentru a vă dezvolta. În acest tutorial, vom vorbi despre noile metode care sunt disponibile pentru dvs..
ECMAScript este numele oficial al ceea ce numim toți JavaScript. Asta nu înseamnă că ne înșelăm; doar că numele "JavaScript" este o marcă comercială a Oracle; astfel încât Ecma International (inițial Asociația Europeană a Producătorilor de Computer - deci ECMA) folosește termenul "ECMAScript" pentru a se referi la standardul de JavaScript. Ultima versiune a acestui standard este ediția a 5-a și a fost aprobată cu puțin peste un an în urmă (la 3 decembrie 2009). Acesta cuprinde o gamă imensă de adăugări extraordinare, iar câteva dintre acestea încep să apară în browsere. Implementările ECMAScript 5 se numesc JavaScript 1.8.5.
În acest tutorial, vom urmări funcțiile JavaScript 1.8.5 care sunt disponibile pentru noi în Firefox 4 beta. Veți fi bucuros să descoperiți că majoritatea celor mai recente versiuni ale altor browsere au și acestea, cu excepția unei singure. De data aceasta, este Opera, așa cum IE9 a inclus multe dintre acestea.
Această metodă este foarte importantă; într-adevăr, curăță moștenirea prototypală. Anterior (în ECMAScript ediția a 3-a), pentru a crea un obiect și pentru a-și seta prototipul, ați face acest lucru:
funcția Cat (nume) this.name = nume; this.paws = 4; this.hungry = false; this.eaten = []; Cat.prototype = constructor: Cat, play: function () this.hungry = true; întoarceți "jocul"; , feed: funcția (mâncare) this.eaten.push (alimente); this.hungry = false; , vorbiți: funcția () return "Meow";
Sunt singurul care crede că pare ciudat să aibă prototipul in afara funcția constructorului? Și moștenirea devine și mai meserioasă. Cu Object.create
, lucrurile devin mult mai ușor. Cele de mai sus ar putea fi codificate astfel:
var câine = nume: "câine", picioare: 4, foame: fals, mâncat: null, play: function () this.hungry = true; întoarceți "jocul"; , feed: funcție (alimentare) if (! this.eaten) this.eaten = []; this.eaten.push (alimente); this.hungry = false; , vorbiți: function () return "Woof!" ; var my_dog = Object.create (câine);
Ce se întâmplă aici este asta: sună object.create
, trecând un obiect de utilizat ca prototip al noului obiect care Object.create
se întoarce. Atunci când se utilizează Object.create
, Nu trebuie să vă faceți griji cu privire la definirea prototipului separat. De fapt, am mult mai multă flexibilitate pentru a decide cum să creez și să moștenesc obiecte. De exemplu, nu pot pune mâncat
array pe prototip, deoarece o matrice este o valoare de referință, deci fiecare obiect creat de câine
va împărți acea matrice. M-am decis să verific eu înainte să o folosesc aici, dar dacă aș vrea să mă împachetez Object.create (câine)
în a make_dog
am putea să o atribuim acolo la fel de ușor.
Asta e grozav Object.create
; puteți alege cum să faceți acest lucru.
Există un al doilea parametru Object.create
ia; este un obiect descriptor de proprietăți. Este un pic cam complicat, dar este, de asemenea, o parte din următoarea funcție pe care o vom analiza, așa că haideți să verificăm asta.
Dacă aveți un obiect pe care doriți să definiți o proprietate, probabil o veți face astfel:
my_dog.age = 2;
Acest lucru funcționează în continuare în ES5, dar dacă doriți un control mai fin, puteți să-l aveți Object.defineProperty
. Primul parametru este obiectul pe care îl alocați proprietății. Al doilea parametru este numele proprietății, ca șir. Proprietatea finală este obiectul descriptor. Iată cum funcționează acest lucru. Este (evident) un obiect și poate avea o combinație a următoarelor proprietăți, toate descriu proprietatea pe care o adăugăm:
nedefinit
.Adevărat
. Implicit la fals
.Adevărat
. Implicit la fals
.fals
.nedefinit
.nedefinit
.Rețineți că valorile implicite pentru opțiunile booleene de mai sus sunt inversa celei vechi obj.prop = val
standarde. De asemenea, știți că nu puteți defini valoare
sau inscriptibil
cand obține
sau a stabilit
sunt definite și invers.
Deci, cum ai folosi asta? Incearca asta:
// presupune ca my_dog de mai sus Object.defineProperty (my_dog, "age", set: function (age) this.human_years = vârsta * 7;, get: function () return this.human_years / 7; : Adevărat ); my_dog.age = 2; my_dog.human_years; // 14
În afară de faptul că ani de câini nu sunt cu adevărat șapte ani, ar trebui să observați că nu am stabilit valoare
sau inscriptibil
aici, pentru că noi folosim obține
și a stabilit
. Aceste funcții nu sunt accesate direct. Acestea sunt "în mod magic" alergate în spatele scenei atunci când atribuiți sau solicitați o proprietate. În acest exemplu, folosesc aceste funcții pentru a le păstra vârstă
și human_years
în "sincronizare". Dacă nu doriți ca valoarea "alta" să fie accesibilă, puteți utiliza o funcție anonimă de auto-invocare pentru ao ascunde cu închidere:
Object.defineProperty (my_dog, "age", (function () var human_years; return set: function (age) human_years = age * 7;, get: function () return human_years / Adevărat ; ()));
Desigur, nimic nu te oprește să faci ceva prost înăuntru obține
sau a stabilit
, astfel încât să-l utilizați cu înțelepciune.
Puteți utiliza o formă a obiectului descriptorului de proprietăți pentru a adăuga proprietăți la obiecte Object.create
. Procedați după cum urmează:
var your_dog = Object.create (câine, age: get: function () / * ... * /, set: function () Femeie" );
Doar folosiți numele proprietății ca proprietate a obiectului descriptor; apoi setați atributele printr-un obiect în valoare.
Dacă doriți să definiți mai multe proprietăți simultan, puteți utiliza un obiect descriptor de proprietăți la fel ca și cu Object.create
pentru a le defini, folosind Object.defineProperties
.
Object.defineProperties (my_dog, age: get: function () / * ... * /, set: function () / * ... * /; );
Veți dori să notați - pentru cazul rar atunci când nu utilizați un obiect literal ca al doilea parametru - că vor fi utilizate numai proprietățile enumerabile ale obiectului de proprietăți.
Dacă vreți să cunoașteți specificul unei proprietăți, puteți utiliza această funcție, Object.getOwnPropertyDescriptor
. Luați notă de "proprii"; acest lucru funcționează numai cu proprietăți pe obiectul propriu-zis, nu pe lanțul său prototip.
var person = nume: "Joe"; Object.getOwnPropertyDescriptor (persoană, "nume"); // configurabil: true, enumerable: true, value: "Joe", scriere: true
După cum puteți vedea, aceasta funcționează cu proprietăți stabilite atât în vechiul, cât și în cel nou. Object.getOwnPropertyDescriptor
are doi parametri: obiectul și numele proprietății ca șir.
V-ați dorit vreodată să obțineți toate cheile unui obiect? Acum, puteți face acest lucru cu ușurință cu Object.keys
. Transmite această funcție un obiect și va returna o matrice din toate proprietățile enumerabile ale acelui obiect. Puteți, de asemenea, să treceți o matrice și veți primi o serie de indicii.
var cal = nume: "Ed", varsta: 4, slujba: "jumping", proprietar: "Jim"; var horse_keys = Object.keys (cal); // ["nume", "vârstă", "loc de muncă", "proprietar"];
Aceasta este exact ca Object.keys
, cu excepția faptului că include toate proprietățile - chiar și cele care nu sunt enumerable. Prin denumirea mai lungă a funcției, puteți spune că descurajează utilizarea acesteia. De obicei, veți dori chei
in schimb.
Dacă ați dorit vreodată să creați o funcție care să nu accepte parametri noi, puteți face acest lucru acum. Rulați obiectul prin Object.preventExtensions
, și va refuza toate încercările de a adăuga noi parametri. Această funcție merge mână în mână cu Object.isExtensible
, care se întoarce Adevărat
dacă puteți extinde obiectul și fals
dacă nu puteți.
var produs = nume: "Foobar", rating: 3,5; Object.isExtensible (produs); // true Object.preventExtenții (produs); Object.isExtensible (produs); // false product.price = "$ 10.00"; // nu funcționează product.price; // nedefinit
Trebuie să rețineți că toate proprietățile de pe obiect în momentul în care executați Object.preventExtensions
pot fi în continuare modificate sau șterse (presupunând că atributele lor permit acest lucru).
Etanșarea unui obiect este cu un pas mai mare decât prevenirea extensiilor. Un obiect sigilat nu vă va permite să adăugați sau să ștergeți proprietăți sau să schimbați proprietățile dintr-o valoare (ca un șir) într-un accesor (o metodă) sau invers. Încă veți putea să citiți și să scrieți proprietăți, desigur. Puteți afla dacă un obiect este sigilat prin utilizarea Object.isSealed
.
var pet = nume: "Browser", tip: "câine"; Object.seal (pet); pet.name = "Oreo"; pet.age = 2; // nu funcționează pet.type = funcția () / ** /; // nu funcționează ștergeți numele de companie; // nu funcționează
Înghețându-l încă un pas mai departe. Un obiect înghețat nu poate fi schimbat în nici un fel; este doar pentru citire. Puteți verifica înghețarea unui obiect, ați ghicit-o, Object.isFrozen
.
var obj = salut: "Bună!" ; Object.freeze (obj); Object.isFrozen (obj); // Adevărat
Ați crede că nu ar fi prea greu să determinați că o anumită variabilă este o matrice. La urma urmei, orice altceva funcționează bine cu tip de
operator. Cu toate acestea, matricele JavaScript sunt de tip inconsecvent. Ele sunt de fapt obiecte mai apropiate de array (chiar dacă de obicei folosim acest termen pentru a se referi la lucruri de genul argumente
și NodeList
s). Această funcție vă oferă o cale de a fi 100% siguri că lucrul cu care lucrați este o matrice. Transmiteți o variabilă și returnează booleanul.
var nume = ["Collis", "Cyan"]; Array.isArray (nume); // Adevărat
Pentru mai multe informații despre motivul pentru care avem nevoie de această funcție, consultați docs-urile legate de cele de mai jos.
Acest lucru nu este prea mare, dar dacă doriți vreodată să păstrați datele în JSON, puteți găsi acest lucru util. Datele de date au acum a toJSON
care va converti data la o dată de șir JSON.
noua dată (). toJSON (); // "2010-12-06T16: 25: 40.040Z"
Probabil sunteți familiarizați cu utilizarea apel
și aplica
pentru a redistribui valoarea acest
într-o funcție.
var arr1 = ["1", "2", "3"], arr2 = ["4", "5", "6"]; Array.prototype.push.apply (arr1, arr2);
Aceste metode vă permit să modificați valoarea acest
în cadrul unei funcții. Dacă doriți să faceți ceva de genul asta des, Function.prototype.bind
returnează o nouă funcție cu acest
legat de tot ce treceți, astfel încât să îl puteți salva la o variabilă.
var tooltip = text: "Faceți clic aici pentru ...", overlay = text: "Introduceți numărul participanților"; funcția show_text () // într-adevăr, faceți ceva mai util aici console.log (this.text); tooltip.show = show_text.bind (tooltip); tooltip.show (); overlay.show = show_text.bind (suprapunere); overlay.show ();
Desigur, acest lucru nu ar putea fi cel mai practic exemplu, dar vă dă ideea!
Acestea sunt funcțiile ECMAScript 5th Edition (sau JavaScript 1.8.5) care au fost adăugate la Firefox 4 beta. Există câteva alte modificări la JavaScript pe care le implementează, de asemenea, pe care le puteți verifica în notele de lansare.
Cu toate acestea, există o mulțime de funcții ECMAScipt 5 care au fost deja acceptate în Firefox 3 și alte câteva browsere. Ai jucat cu oricare dintre acestea?
Notă: acestea sunt legate de documentația MDN.
Dacă doriți să vedeți ce browsere și versiuni acceptă aceste funcții, puteți verifica acest tabel de compatibilitate, realizat de Juriy Zaytsev (Kangax). Lucru frumos despre cele mai multe dintre aceste funcții este că, dacă un browser nu îl suportă, de obicei puteți adăuga suport, cu ceva de genul:
dacă (tipul Object.create! == 'funcția') Object.create = funcția (o) funcția F () F.prototype = o; returnează noul F (); ; // Courtesy of Douglas Crockford: http://javascript.crockford.com/prototypal.html
Uclarea noilor funcții pe care le-am analizat aici este într-adevăr o mică parte a bunătății adăugate standardului ECMAScript în a 5-a ediție. Există alte caracteristici pe care sunteți în mod special căutați cu nerăbdare să le utilizați, sau chiar folosind chiar acum? Haideți aici în comentariile!