Satu contoh melibatkan penutupan, yang lain tidak. Menerapkan penutupan agak rumit, karena variabel tertutup tidak berfungsi seperti variabel normal. Ini lebih jelas dalam bahasa tingkat rendah seperti C, tapi saya akan menggunakan JavaScript untuk menggambarkan ini.
Penutupan tidak hanya terdiri dari suatu fungsi, tetapi juga dari semua variabel yang ditutup. Ketika kita ingin menjalankan fungsi itu, kita juga perlu menyediakan semua variabel yang ditutup. Kita bisa memodelkan penutupan dengan fungsi yang menerima objek sebagai argumen pertama yang mewakili variabel tertutup ini:
function add(vars, y) {
vars.x += y;
}
function getSum(vars) {
return vars.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(adder, 2);
console.log(adder.getSum(adder)); //=> 42
Perhatikan konvensi pemanggilan yang canggung yang closure.apply(closure, ...realArgs)
diperlukan
Dukungan objek bawaan JavaScript memungkinkan untuk menghilangkan vars
argumen eksplisit , dan this
sebagai gantinya kami menggunakan :
function add(y) {
this.x += y;
}
function getSum() {
return this.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
Contoh-contoh itu setara dengan kode ini yang benar-benar menggunakan closure:
function makeAdder(x) {
return {
add: function (y) { x += y },
getSum: function () { return x },
};
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
Dalam contoh terakhir ini, objek hanya digunakan untuk mengelompokkan dua fungsi yang dikembalikan; yang this
mengikat tidak relevan. Semua perincian untuk membuat penutupan mungkin - meneruskan data tersembunyi ke fungsi aktual, mengubah semua akses ke variabel penutupan untuk mencari dalam data tersembunyi - diurus oleh bahasa.
Tetapi penutupan panggilan melibatkan overhead melewatkan data tambahan itu, dan menjalankan penutupan melibatkan overhead pencarian dalam data tambahan - diperburuk oleh lokalitas cache yang buruk dan biasanya penunjuk dereferensi bila dibandingkan dengan variabel biasa - sehingga tidak mengherankan bahwa solusi yang tidak bergantung pada penutupan berkinerja lebih baik. Terutama karena semua penutupan Anda menghemat Anda lakukan adalah beberapa operasi aritmatika yang sangat murah, yang bahkan mungkin dilipat konstan selama parsing.