Modifikasi Objek ECMAScript

Dengan menggunakan ECMAScript, bukan hanya dapat membuat objek, tetapi juga dapat mengubah perilaku objek yang sudah ada.

Atribut prototype dapat mendefinisikan atribut dan metode konstraktor, serta menambah atribut dan metode untuk objek lokal.

Membuat metode baru

Membuat metode baru melalui metode yang sudah ada

Kami dapat menggunakan properti prototype untuk mendefinisikan metode baru untuk kelas yang sudah ada, seperti mengatur kelas sendiri. Contohnya, ingat metode toString() kelas Number? Jika diberikan parameter 16, ia akan menampilkan string heksadesimal. Jika parameter metode ini adalah 2, maka ia akan menampilkan string biner. Kita dapat membuat metode yang dapat mengkonversi objek angka langsung ke string heksadesimal. Membuat metode ini sangat mudah:

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

Dalam lingkungan ini, kata kunci this menunjuk ke instansi Number, sehingga dapat mengakses semua metode Number. Dengan kode ini, kita dapat melaksanakan operasi di bawah ini:

var iNum = 15;
alert(iNum.toHexString());		//Output "F"

Try It Yourself (TIY)

Karena angka 15 sama dengan F di heksadesimal, peringatan akan menampilkan "F".

Mengubah nama metode yang sudah ada

Kami juga dapat menamakan metode yang sudah ada dengan nama yang lebih mudah memahami. Contohnya, kita dapat menambahkan dua metode enqueue() dan dequeue() ke kelas Array, hanya memanggil metode push() dan shift() yang sudah ada saja:

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

Try It Yourself (TIY)

Menambahkan metode yang tidak berhubungan dengan metode yang sudah ada

Tentu, kita dapat menambahkan metode yang tidak berhubungan dengan metode yang sudah ada. Contohnya, asumsikan kita ingin mengecek posisi suatu item di dalam array, tidak ada metode lokal yang dapat melakukan hal ini. Kita dapat dengan mudah membuat metode di bawah ini:

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

Metode indexOf() ini sejalan dengan metode yang sama di kelas String, mencari setiap item di dalam array sampai menemukan item yang sama yang diberikan. Jika menemukan item yang sama, maka kembalikan posisi item tersebut, jika tidak, kembalikan -1. Dengan definisi ini, kita dapat menulis kode di bawah ini:

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	//keluarkan "1"

Try It Yourself (TIY)

Menambahkan metode baru ke objek lokal

Akhirnya, jika Anda ingin menambahkan metode baru ke setiap objek lokal di ECMAScript, Anda harus mendefinisikannya di properti prototype objek Object. Seperti yang disebutkan di bab sebelumnya, semua objek lokal mewarisi objek Object, jadi setiap perubahan yang Anda lakukan terhadap objek Object akan berpengaruh terhadap semua objek lokal. Contohnya, jika Anda ingin menambahkan metode untuk menampilkan nilai objek saat ini dengan peringatan, Anda dapat menggunakan kode berikut:

Object.prototype.showValue = function () {
  alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue();		//keluarkan "hello"
iNum.showValue();		//keluarkan "25"

Try It Yourself (TIY)

Di sini, objek String dan Number mewarisi metode showValue() dari objek Object, memanggil metodenya di atas objek masing-masing, akan menampilkan "hello" dan "25".

Menimbulkan kembali metode yang sudah ada

Seperti yang dapat memberikan definisi kelas baru untuk kelas yang sudah ada, Anda juga dapat menimbulkan kembali metode yang sudah ada. Seperti yang disebutkan di bab sebelumnya, nama fungsi hanya penunjuk ke fungsi, jadi dapat dengan mudah menunjuk ke fungsi lain. Jika Anda mengubah metode lokal, seperti toString(), apa yang akan terjadi?

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

Kode sebelumnya sepenuhnya sah, hasil eksekusi sepenuhnya sesuai dengan harapan:

function sayHi() {
  alert("hi");
}
alert(sayHi.toString());	//keluarkan "Function code hidden"

Try It Yourself (TIY)

Mungkin Anda ingat, di bab Function object ini disebutkan bahwa metode toString() biasanya mengeluarkan kode sumber fungsi. Menimbulkan metode ini, dapat mengembalikan string lainnya (di contoh ini, dapat mengembalikan "Function code hidden"). Namun, apa yang terjadi dengan fungsi asli yang diarahkan toString()? Dia akan disaring oleh program pengembalian memori yang tidak digunakan, karena sepenuhnya diabaikan. Tidak ada metode untuk memulihkan fungsi asli, jadi cara yang aman sebelum menimbulkan metode asli adalah menyimpan penunjuknya untuk penggunaan nanti. Kadang-kadang Anda bahkan dapat memanggil metode asli di dalam metode baru:

Function.prototype.originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};

Try It Yourself (TIY)

In this code, the first line saves the reference to the current toString() method in the property originalToString. Then, a custom method overrides the toString() method. The new method checks if the length of the function source code is greater than 100. If it is, it returns an error message indicating that the function code is too long, otherwise it calls the originalToString() method and returns the source code of the function.

Very Late Binding (Very Late Binding)

Technically, there is no such thing as very late binding. This book uses this term to describe a phenomenon in ECMAScript, where methods can be defined after the object is instantiated. For example:

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

Try It Yourself (TIY)

In most programming languages, it is necessary to define the methods of an object before instantiating the object. Here, the method sayHi() is added after creating an instance of the Object class. In traditional languages, not only have I never heard of this operation, but I have also never heard that this method would automatically assign to the instance of the Object object and can be used immediately (in the next line).

Note:It is not recommended to use very late binding methods because it is difficult to track and record them. However, it is still important to understand this possibility.