Επεξεργασία Οντότητας ECMAScript

Με τη χρήση του ECMAScript, μπορεί όχι μόνο να δημιουργηθούν αντικείμενα, αλλά και να τροποποιηθεί το συμπεριφορά των υπάρχοντων αντικειμένων.

Η ιδιότητα του prototype μπορεί όχι μόνο να καθορίσει τις ιδιότητες και τις μεθόδους του κατασκευαστή, αλλά και να προσθέσει ιδιότητες και μεθόδους στο τοπικό αντικείμενο.

Δημιουργία νέων μεθόδων

Δημιουργία νέων μεθόδων μέσω υπάρχουσων μεθόδων

Μπορείτε να χρησιμοποιήσετε την ιδιότητα prototype για να ορίσετε νέες μεθόδους σε οποιαδήποτε υπάρχουσα κλάση, όπως να χειρίζεστε την κλάση σας. Για παράδειγμα, θυμάστε τη μέθοδο toString() της κλάσης Number; Αν της δώσετε ως παράμετρο τον αριθμό 16, θα εκτυπώσει την δεκαεξαδική αλφαριθμητική αλυσίδα. Αν η παράμετρος είναι 2, θα εκτυπώσει την βιναριτική αλυσίδα. Μπορούμε να δημιουργήσουμε μια μέθοδο που θα μετατρέπει απευθείας ένα αντικείμενο αριθμού σε δεκαεξαδική αλφαριθμητική αλυσίδα. Η δημιουργία αυτής της μεθόδου είναι πολύ εύκολη:

Number.prototype.toHexString = function() {
  return this.toString(16);
};

Σε αυτό το περιβάλλον, το κλειδί this αναφέρεται σε μια εικονική παράσταση του Number, οπότε μπορείτε να προσέξετε όλες τις μεθόδους του Number. Με αυτόν τον κώδικα, μπορείτε να επιτύχετε τις παρακάτω ενέργειες:

var iNum = 15;
alert(iNum.toHexString());		// Εκτύπωση "F"

TIY

Επειδή ο αριθμός 15 ισούται με το F σε δεκαεξαδικό, η προειδοποίηση θα εμφανιστεί ως "F".

Μετονομασία υπάρχουσων μεθόδων

Μπορούμε επίσης να δώσουμε πιο κατανοητά ονόματα στις υπάρχουσες μεθόδους. Για παράδειγμα, μπορούμε να προσθέσουμε δύο μεθόδους enqueue() και dequeue() στην κλάση Array, που καλούν μόνο τις υπάρχουσες μεθόδους push() και shift():

Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};
Array.prototype.dequeue = function() {
  return this.shift();
};

TIY

Προσθήκη μεθόδων που δεν σχετίζονται με τις υπάρχουσες

Φυσικά, μπορείτε να προσθέσετε μεθόδους που δεν σχετίζονται με τις υπάρχουσες μεθόδους. Για παράδειγμα, υποθέτουμε ότι θέλετε να δείτε τη θέση ενός στοιχείου στην ακολουθία, δεν υπάρχει τοπική μέθοδος που μπορεί να το κάνει αυτό. Μπορούμε να δημιουργήσουμε εύκολα τη παρακάτω μέθοδο:

Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
	  return i;
	}
  }
  return -1;
}

Η μέθοδος indexOf() είναι ίδια με τη συναρμογή της String, αναζητά κάθε στοιχείο της ακολουθίας μέχρι να βρει το στοιχείο που έχει传入. Αν βρει το ίδιο στοιχείο, επιστρέφει τη θέση του, διαφορετικά επιστρέφει -1. Με αυτή τη διάκριση, μπορούμε να γράψουμε τον παρακάτω κώδικα:

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	//εκτυπώνει "1"

TIY

Προσθήκη νέων μεθόδων σε τοπικά αντικείμενα

Τελικά, αν θέλεις να προσθέσεις νέες μεθόδους σε κάθε τοπικό αντικείμενο του ECMAScript, πρέπει να τις ορίσεις στη ιδιότητα prototype του αντικειμένου Object. Όπως αναφέρθηκε σε προηγούμενα κεφάλαια, όλα τα τοπικά αντικείμενα κληρονομούν το αντικείμενο Object, οπότε οποιαδήποτε αλλαγή στο αντικείμενο Object θα επηρεάσει όλα τα τοπικά αντικείμενα. Για παράδειγμα, αν θέλεις να προσθέσεις μια μέθοδο που εκτυπώνει την τρέχουσα τιμή του αντικειμένου με ένα μήνυμα προειδοποίησης, μπορείς να χρησιμοποιήσεις τον παρακάτω κώδικα:

Object.prototype.showValue = function () {
  alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue();		//εκτυπώνει "hello"
iNum.showValue();		//εκτυπώνει "25"

TIY

Εδώ, τα αντικείμενα String και Number κληρονομούν τη μέθοδο showValue() από το αντικείμενο Object, και όταν καλούνται αυτές οι μεθόδους στα αντικείμενα τους, θα εμφανιστούν "hello" και "25".

Επαναπροσδιορισμός υπάρχουσας μεθόδου

Όπως μπορείς να προσθέσεις νέες μεθόδους σε υπάρχουσες ορισμένες κλάσεις, μπορείς επίσης να επαναπροσδιορίσεις υπάρχουσες μεθόδους. Καθώς αναφέρθηκε σε προηγούμενα κεφάλαια, το όνομα της συνάρτησης είναι απλώς ένας δείκτης προς τη συνάρτηση, οπότε μπορεί να δείχνει σε άλλες συναρτήσεις. Αν αλλάξεις το τοπικό μέθοδο, όπως η toString(), τι θα συμβεί;

Function.prototype.toString = function() {
  return "Function code hidden";
}

Ο κώδικας που προηγείται είναι πλήρως νόμιμος και ο αποτέλεσμας του εκτυπώνει όπως αναμενόταν:

function sayHi() {
  alert("hi");
}
alert(sayHi.toString());	//εκτυπώνει "Function code hidden"

TIY

Μπορείς να θυμάσαι, στο κεφάλαιο για το αντικείμενο Function, αναφέρθηκε η μέθοδος toString() της function που συνήθως εκτυπώνει τον κώδικα της συνάρτησης. Η επανασύνδεση αυτής της μεθόδου μπορεί να επιστρέψει μια άλλη αλφαριθμητική ακολουθία (στον παρόντα παράδειγμα, μπορεί να επιστρέψει "Function code hidden"). Ωστόσο, τι συμβαίνει με την αρχική συνάρτηση που στοχεύει η toString(); Θα συλλεγεί από το πρόγραμμα ανακύκλωσης ανεπαχθής αποθήκευσης, επειδή έχει απορριφθεί πλήρως. Δεν υπάρχει τρόπος να ανακτήσουμε την αρχική συνάρτηση, οπότε η πιο ασφαλής πρακτική πριν από την επανασύνδεση της αρχικής μεθόδου είναι να αποθηκεύσουμε τον δείκτη της, ώστε να μπορούμε να τη χρησιμοποιήσουμε στο μέλλον. Σε ορισμένες περιπτώσεις, μπορείς να καλέσεις την αρχική μέθοδο μέσα στην νέα μέθοδο:

Function.prototype.originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Η συνάρτηση είναι πολύ μεγάλη για να εμφανιστεί.";
  } else {
    return this.originalToString();
  }
};

TIY

Σε αυτό το κείμενο κώδικα, η πρώτη γραμμή κώδικα αποθηκεύει την αναφορά στην μέθοδο toString() στην ιδιότητα originalToString. Στη συνέχεια, καλύπτεται η μέθοδος toString() με μια προσαρμοσμένη μέθοδο. Η νέα μέθοδος θα ελέγξει αν η μήκος του κώδικα της συνάρτησης είναι μεγαλύτερη από 100. Αν ναι, θα επιστρέψει ένα μήνυμα σφάλματος που δείχνει ότι ο κώδικας της συνάρτησης είναι πολύ μεγάλος, αλλιώς θα καλέσει τη μέθοδο originalToString() και θα επιστρέψει τον κώδικα της συνάρτησης.

极晚绑定 (Very Late Binding)

Εκ του τεχνικού, δεν υπάρχει καθόλου极晚绑定. Το βιβλίο χρησιμοποιεί τον όρο αυτό για να περιγράψει ένα φαινόμενο στο ECMAScript, όπου είναι δυνατό να οριστούν μεθόδους ενός αντικειμένου μετά την instantiation του αντικειμένου. Για παράδειγμα:

var o = new Object();
Object.prototype.sayHi = function () {
  alert("hi");
};
o.sayHi();

TIY

Σε πολλές γλώσσες προγραμματισμού, πρέπει να ορίσετε τα μεθόδους του αντικειμένου πριν από την instantiation του αντικειμένου. Εδώ, η μέθοδος sayHi() προστίθεται μετά την δημιουργία μιας instance της κλάσης Object. Σε παραδοσιακές γλώσσες, δεν έχει ακούσει κανείς για αυτήν την πράξη, και δεν έχει ακούσει ότι η μέθοδος αυτή αποδίδεται αυτόματα στην instance του αντικειμένου Object και μπορεί να χρησιμοποιηθεί αμέσως (στο επόμενο σύνταγμα).

Σημείωση:Δεν συνιστάται η χρήση της μεθόδου极晚绑定, επειδή είναι δύσκολο να την παρακολουθήσετε και να την καταγράψετε. Ωστόσο, πρέπει να κατανοήσετε αυτή την πιθανότητα.