Cosa c'è di nuovo in JavaScript 1.8.5

È un ottimo momento per JavaScript. Non solo sta diventando una lingua molto più rispettata, ma sta anche crescendo a passi da gigante - sia in termini di popolarità che di funzionalità. Man mano che altri browser iniziano a implementare le funzionalità dello standard ECMAScript 5th edition, JavaScript diventa una piattaforma ancora più potente su cui sviluppare. In questo tutorial parleremo dei nuovi metodi disponibili.


Cos'è ECMAScript 5?

ECMAScript è il nome ufficiale di ciò che tutti chiamiamo JavaScript. Ciò non significa che abbiamo torto; è solo che il nome "JavaScript" è un marchio di fabbrica di Oracle; così Ecma International (in origine l'European Computer Manufacturers Association - da qui l'ECMA) usa il termine "ECMAScript" per riferirsi allo standard di JavaScript. L'ultima versione di questo standard è la quinta edizione ed è stata approvata poco più di un anno fa (il 3 dicembre 2009). Comprende una vasta gamma di grandi aggiunte e molte di queste stanno iniziando a essere visualizzate nei browser. Le implementazioni di ECMAScript 5 sono chiamate JavaScript 1.8.5.

In questo tutorial, esamineremo le funzioni di JavaScript 1.8.5 che sono a nostra disposizione nelle beta di Firefox 4. Sarai felice di scoprire che la maggior parte delle ultime versioni di altri browser hanno anche questi ... tranne uno. Questa volta, è Opera, come IE9 ha incluso molti di questi.


Funzione 1: Object.create

Questo metodo è molto importante; pulisce davvero l'eredità prototipale. In precedenza (in ECMAScript 3a edizione), per creare un oggetto e impostarne il prototipo, dovresti fare qualcosa del genere:

funzione Cat (nome) this.name = nome; this.paws = 4; this.hungry = false; this.eaten = [];  Cat.prototype = costruttore: Cat, play: function () this.hungry = true; ritorna "giocando!"; , feed: function (food) this.eaten.push (cibo); this.hungry = false; , speak: function () return "Meow";

Sono l'unico a pensare che sembra strano avere il prototipo al di fuori la funzione del costruttore? E l'ereditarietà diventa ancora più caotica. Con Object.create, le cose diventano molto più facili. Quanto sopra potrebbe essere codificato in questo modo:

var dog = nome: "cane", zampe: 4, affamato: falso, mangiato: null, play: function () this.hungry = true; ritorna "giocando!"; , feed: function (food) if (! this.eaten) this.eaten = [];  this.eaten.push (cibo); this.hungry = false; , speak: function () return "Woof!" ; var my_dog = Object.create (cane);

Quello che sta succedendo qui è questo: sto chiamando object.create, passandogli un oggetto da utilizzare come prototipo del nuovo oggetto Object.create sta tornando. Quando si usa Object.create, Non devo preoccuparmi di definire il prototipo separatamente. In effetti, ho molta più flessibilità per decidere come procedere per creare ed ereditare oggetti. Ad esempio, non riesco a mettere il mangiato array sul prototipo, perché un array è un valore di riferimento, quindi ogni oggetto creato da cane condividerò quell'array. Ho deciso di controllarlo prima di usarlo qui, ma se volessi avvolgere Object.create (cane) in un make_dog funzione, potrei assegnarlo lì altrettanto facilmente.

Questo è il bello Object.create; puoi scegliere come farlo.

C'è un secondo parametro Object.create prende; è un oggetto descrittore di proprietà. È un po 'complicato, ma è anche una parte della prossima funzione che vedremo, quindi diamo un'occhiata.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+

Funzione 2: Object.defineProperty

Se hai un oggetto su cui vuoi definire una proprietà, probabilmente lo farai in questo modo:

my_dog.age = 2;

Funziona ancora bene con ES5, ma se vuoi un controllo più preciso, puoi farlo con Object.defineProperty. Il primo parametro è l'oggetto a cui stai assegnando la proprietà. Il secondo parametro è il nome della proprietà, come una stringa. La proprietà finale è l'oggetto descrittore. Ecco come funziona. È (ovviamente) un oggetto e può avere una combinazione delle seguenti proprietà, ognuna delle quali descrive la proprietà che stiamo aggiungendo:

  • valore: usa questo per impostare il valore di una proprietà. Predefinito a non definito.
  • scrivibile: usa questo valore booleano per definire se si tratta di una variabile di sola lettura. Se è scrivibile, lo è vero. Predefinito a falso.
  • configurabile: usa questo valore booleano per definire se il tipo (valore vs. metodo) di questa proprietà può essere modificato o se la proprietà può essere cancellata. Se è configurabile, lo è vero. Predefinito a falso.
  • enumerabile: usa questo valore booleano per definire se questa proprietà è inclusa quando le proprietà dell'oggetto sono enumerate (un ciclo for-in o il metodo keys). Predefinito a falso.
  • ottenere: usa questo per definire un metodo getter personalizzato. Predefinito a non definito.
  • impostato: usa questo per definire un metodo setter personalizzato. Predefinito a non definito.

Si noti che i valori predefiniti per le opzioni booleane sopra riportate sono il contrario del vecchio obj.prop = val standard. Inoltre, sappi che non puoi definire valore o scrivibile quando ottenere o impostato sono definiti e viceversa.

Quindi, come useresti questo? Prova questo:

// presume my_dog da sopra Object.defineProperty (my_dog, "age", set: function (age) this.human_years = age * 7;, get: function () return this.human_years / 7;, enumerable : vero ); my_dog.age = 2; my_dog.human_years; // 14

A parte il fatto che gli anni del cane non sono in realtà 7 anni umani, dovresti notare che non abbiamo impostato valore o scrivibile qui, perché stiamo usando ottenere e impostato. Queste funzioni non sono mai accessibili direttamente. Sono "magicamente" corri dietro le quinte quando assegni o chiedi una proprietà. In questo esempio, sto usando queste funzioni per mantenere età e human_years in "sync". Se non si desidera che il valore "other" sia accessibile, è possibile utilizzare una funzione anonima di auto-richiamo per nasconderlo con la chiusura:

Object.defineProperty (my_dog, "age", (function () var human_years; return set: function (age) human_years = age * 7;, get: function () return human_years / 7;, enumerable: vero ; ()));

Certo, non c'è niente che ti impedisca di fare qualcosa di stupido dentro ottenere o impostato, quindi usalo saggiamente.

È possibile utilizzare un modulo dell'oggetto descrittore di proprietà per aggiungere proprietà agli oggetti Object.create. Fallo come segue:

var your_dog = Object.create (dog, age: get: function () / * ... * /, set: function () / * ... * /, enumerable: true, gender: value: " femmina ");

Basta usare il nome della proprietà come proprietà dell'oggetto descrittore; quindi, imposta gli attributi tramite un oggetto nel valore.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+

Funzione 3: Object.defineProperties

Se si desidera definire più proprietà contemporaneamente, è possibile utilizzare un oggetto descrittore di proprietà proprio come con Object.create per definirli, usando Object.defineProperties.

Object.defineProperties (my_dog, age: get: function () / * ... * /, set: function () / * ... * /, enumerable: true, gender: value: "female" );

Avrai voglia di notare - per il raro caso in cui non utilizzi un oggetto letterale come secondo parametro - che verranno utilizzate solo le proprietà enumerabili dell'oggetto properties.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+

Funzione 4: Object.getOwnPropertyDescriptor

Se si desidera conoscere le specifiche di una proprietà, è possibile utilizzare questa funzione, Object.getOwnPropertyDescriptor. Prendi nota del "Proprio"; questo funziona solo con le proprietà sull'oggetto stesso, non sulla sua catena di prototipi.

var person = name: "Joe"; Object.getOwnPropertyDescriptor (person, "name"); // configurabile: true, enumerable: true, value: "Joe", scrivibile: true

Come puoi vedere, questo funziona con le proprietà impostate sia nel vecchio che nel nuovo modo. Object.getOwnPropertyDescriptor prende due parametri: l'oggetto e il nome della proprietà come una stringa.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 8+
    • Safari 5
    • Chrome 5+

Funzione 5: Object.keys

Hai mai voluto ottenere tutte le chiavi di un oggetto? Ora puoi farlo facilmente con Object.keys. Passa a questa funzione un oggetto e restituirà una matrice di tutte le proprietà enumerabili di quell'oggetto. Puoi anche passargli una matrice, e otterrai una serie di indici.

var horse = name: "Ed", età: 4, lavoro: "saltando", proprietario: "Jim"; var horse_keys = Object.keys (cavallo); // ["nome", "età", "lavoro", "proprietario"];
  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+

Funzione 6: Object.getOwnPropertyNames

Questo è proprio come Object.keys, tranne che include tutte le proprietà, anche quelle non sono enumerabile. Con il nome della funzione più lungo, puoi dire che scoraggiano l'uso di esso. Di solito, vorresti chiavi anziché.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+

Funzione 7: Object.preventExtensions / Object.isExtensible

Se hai mai desiderato creare una funzione che non accetta nuovi parametri, puoi farlo ora. Gestisci il tuo oggetto Object.preventExtensions, e rifiuterà tutti i tentativi di aggiungere nuovi parametri. Questa funzione va di pari passo con Object.isExtensible, che ritorna vero se puoi estendere l'oggetto e falso se non puoi.

 var product = name: "Foobar", valutazione: 3.5; Object.isExtensible (prodotto); // true Object.preventExtentions (prodotto); Object.isExtensible (prodotto); // false product.price = "$ 10.00"; // non funziona product.price; // non definito

Si noti che tutte le proprietà sull'oggetto al momento dell'esecuzione Object.preventExtensions può ancora essere cambiato o cancellato (assumendo che i loro attributi lo consentano).

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Chrome 6+

Funzione 8: Object.seal / Object.isSealed

Sigillare un oggetto è un passo avanti rispetto alla prevenzione delle estensioni. Un oggetto sigillato non ti consente di aggiungere o eliminare proprietà o di modificare le proprietà da un valore (come una stringa) a un accessorio (un metodo) o viceversa. Sarai comunque in grado di leggere e scrivere proprietà, ovviamente. Puoi scoprire se un oggetto è sigillato usando Object.isSealed.

var pet = nome: "Browser", digitare: "dog"; Object.seal (pet); pet.name = "Oreo"; pet.age = 2; // non funziona pet.type = function () / ** /; // non funziona delete pet.name; // non funziona
  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Chrome 6+

Funzione 9: Object.freeze / Object.isFrozen

Congelarlo ancora un altro passo avanti. Un oggetto congelato non può essere modificato in alcun modo; è di sola lettura. Puoi verificare il congelamento di un oggetto con, hai indovinato, Object.isFrozen.

var obj = saluto: "Ciao!" ; Object.freeze (obj); Object.isFrozen (obj); // vero
  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Chrome 6+

Funzione 10: Array.isArray

Penseresti che non sarebbe troppo difficile determinare che una determinata variabile sia una matrice. Dopotutto, tutto il resto funziona bene con tipo di operatore. Tuttavia, gli array JavaScript sono di tipo inconsistente. In realtà sono oggetti simili ad array più vicini (anche se di solito usiamo questo termine per riferirci a cose come argomenti e NodeListS). Questa funzione ti dà il modo di essere sicuro al 100% che quello con cui stai lavorando è un array. Passa una variabile e restituisce il valore booleano.

var names = ["Collis", "Cyan"]; Array.isArray (nomi); // vero

Per ulteriori informazioni sul motivo per cui abbiamo bisogno di questa funzione, controlla i documenti, collegati qui sotto.

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+
    • Opera 10.5+

Funzione 11: Date.prototype.toJSON

Questo non è troppo grande, ma se vuoi memorizzare le date in JSON, potresti trovarlo utile. Gli oggetti data ora hanno un toJSON funzione che convertirà la data in una data stringa JSON.

new Date (). toJSON (); // "2010-12-06T16: 25: 40.040Z"
  • Documentazione MDN

Funzione 12: Function.prototype.bind

Probabilmente hai familiarità con l'utilizzo chiamata e applicare riassegnare il valore di Questo in una funzione.

var arr1 = ["1", "2", "3"], arr2 = ["4", "5", "6"]; Array.prototype.push.apply (arr1, arr2);

Questi metodi ti permettono di cambiare il valore di Questo all'interno di una funzione. Se vuoi fare qualcosa di simile spesso, Function.prototype.bind restituisce una nuova funzione con Questo legato a qualsiasi cosa tu passi, così puoi salvarlo su una variabile.

var tooltip = text: "Fai clic qui per ...", overlay = text: "Inserisci il numero di partecipanti"; function show_text () // davvero, fai qualcosa di più utile qui console.log (this.text);  tooltip.show = show_text.bind (tooltip); tooltip.show (); overlay.show = show_text.bind (overlay); overlay.show ();

Naturalmente, questo potrebbe non essere l'esempio più pratico, ma ti dà l'idea!

  • Documentazione MDN
  • Supporto del browser
    • Firefox 4
    • Internet Explorer 9
    • Chrome 7+

Ma aspetta, c'è di più ...

Quelle sono le funzioni ECMAScript 5th Edition (o JavaScript 1.8.5) che sono state aggiunte alle beta di Firefox 4. Ci sono alcune altre modifiche a JavaScript che stanno implementando, che puoi verificare nelle note di rilascio.

Tuttavia, ci sono un sacco di funzioni di ECMAScipt 5 che erano già supportate in Firefox 3 e in molti altri browser. Hai giocato con qualcuno di questi?

  • Object.getPrototypeOf
  • String.prototype.trim
  • Array.prototype.indexOf
  • Array.prototype.lastIndexOf
  • Array.prototype.every
  • Array.prototype.some
  • Array.prototype.forEach
  • Array.prototype.map
  • Array.prototype.filter
  • Array.prototype.reduce
  • Array.prototype.reduceRight

Nota: questi sono collegati alla loro documentazione MDN.

Se vuoi vedere quali browser e versioni supportano queste funzioni, puoi consultare questa tabella di compatibilità, creata da Juriy Zaytsev (Kangax). La cosa bella della maggior parte di queste funzioni è che se un browser non lo supporta, di solito puoi aggiungere il supporto, con qualcosa di simile a questo:

if (typeof Object.create! == 'function') Object.create = function (o) function F ()  F.prototype = o; ritorna nuovo F (); ;  // Per gentile concessione di Douglas Crockford: http://javascript.crockford.com/prototypal.html

Quali funzionalità di ECMAScript 5 stai usando?

La gran quantità di nuove funzioni che abbiamo visto qui è solo una piccola parte della bontà aggiunta allo standard ECMAScript nella quinta edizione. Ci sono altre funzionalità che stai specificatamente non vedendo l'ora di usare, o forse addirittura usare adesso? Andiamo qui nei commenti!