Mengikuti ekstrak dari Penutupan: Panduan Definitif oleh Michael Bolin . Ini mungkin terlihat agak panjang, tetapi penuh dengan banyak wawasan. Dari "Lampiran B. Konsep JavaScript yang Sering Disalahpahami":
Apa yang this
Merujuk Ketika Suatu Fungsi Dipanggil
Saat memanggil fungsi formulir foo.bar.baz()
, objek foo.bar
disebut sebagai penerima. Ketika fungsi dipanggil, itu adalah penerima yang digunakan sebagai nilai untuk this
:
var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
for (var i = 0; i < arguments.length; i++) {
this.value += arguments[i];
}
return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);
Jika tidak ada penerima eksplisit ketika suatu fungsi dipanggil, maka objek global menjadi penerima. Seperti yang dijelaskan dalam "goog.global" di halaman 47, jendela adalah objek global ketika JavaScript dieksekusi di browser web. Ini mengarah pada beberapa perilaku mengejutkan:
var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN
Meskipun obj.addValues
dan f
merujuk ke fungsi yang sama, mereka berperilaku berbeda ketika dipanggil karena nilai penerima berbeda di setiap panggilan. Untuk alasan ini, saat memanggil fungsi yang merujuk this
, penting untuk memastikan bahwa this
akan memiliki nilai yang benar ketika dipanggil. Agar jelas, jika this
tidak dirujuk dalam fungsi tubuh, maka perilaku f(20)
dan obj.addValues(20)
akan sama.
Karena fungsi adalah objek kelas satu dalam JavaScript, mereka dapat memiliki metode mereka sendiri. Semua fungsi memiliki metode call()
dan apply()
yang memungkinkan untuk mendefinisikan ulang penerima (yaitu objek yang this
merujuk) ketika memanggil fungsi. Tanda tangan metode adalah sebagai berikut:
/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;
Perhatikan bahwa satu-satunya perbedaan antara call()
dan apply()
yang call()
menerima parameter fungsi sebagai argumen individual, sedangkan apply()
menerimanya sebagai array tunggal:
// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);
Panggilan berikut ini setara, seperti f
dan obj.addValues
merujuk ke fungsi yang sama:
obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);
Namun, karena keduanya call()
tidak apply()
menggunakan nilai penerimanya sendiri untuk menggantikan argumen penerima ketika tidak ditentukan, hal berikut ini tidak akan berfungsi:
// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);
Nilai this
tidak pernah bisa null
atau undefined
ketika suatu fungsi dipanggil. Ketika null
atau undefined
diberikan sebagai penerima ke call()
atau apply()
, objek global digunakan sebagai nilai untuk penerima sebagai gantinya. Oleh karena itu, kode sebelumnya memiliki efek samping yang tidak diinginkan yang sama dengan menambahkan properti yang dinamai value
ke objek global.
Mungkin bermanfaat untuk menganggap suatu fungsi sebagai tidak memiliki pengetahuan tentang variabel yang ditugaskan padanya. Ini membantu memperkuat gagasan bahwa nilai ini akan terikat ketika fungsi dipanggil daripada ketika itu didefinisikan.
Akhir ekstrak.
a
di terapkan untuk array argumen danc
panggilan untuk kolom argumen.