Press "Enter" to skip to content

Mengenal dan Menggunakan Closures Pada Javascript

Sebelum membahas closures, kita harus terlebih dahulu memahami konsep scope pada Javascript. Tidak seperti bahasa pemrograman pada umumnya, pada Javascript tidak ada curly braces scope (ES6 memperkenalkan kata kunci let untuk block-scoped), yang ada hanya function scope.

Jika sebuah variabel didefinisikan dalam sebuah function maka variabel itu tidak bisa diakses diluar function, tapi variabel yang didefinisikan dalam blok code (if atau loop) bisa diakses dari luar blok.
Contoh:

>> var x = 7;
>> function y() {var z = 8; return x;}
>> y();
     7
>> z
      ReferenceError: z is not defined

Variabel x berada pada global scope sedangkan z berada didalam function scope, oleh karena itu bisa diambil kesimpulan bahwa didalam function – z dan x terlihat, sedangkan diluar function x terlihat sedangkan z tidak.

Jika anda mendefinisikan sebuah fungsi v() yang bersarang didalam y() maka v() akan memiliki scope sendiri, tidak hanya itu, v() juga dapat mengakses scope diatasnya (parents), ini dinamakan scope chain (rantai scope), dan anda boleh membuat chain sesuai dengan kebutuhan anda.
Contoh:

>>var x = 7;
>>function y() {
       var z = 8;
           function v() {
              var w = 9;
           }
        }

Pada Javascript, function membuat scope pada saat didefinisikan, bukan pada saat eksekusi, hal ini disebut lexical scope.
Contoh:

>> function x() {var z = 8; y();}
>> function y() {return z;}
>> x() ;
     ReferenceError: z is not defined

function x() dan y() sama-sama memiliki scope lokal namun tidak saling berbagi. Pada saat function y() didefinisikan, z tidak terlihat, begitu juga dengan x(). Lain halnya jika sebuah variabel global z dideklarasikan.
Contoh:

>> function x() {var z = 8; return y();}
>> function y() {return z;}
>> x();
     ReferenceError: z is not defined
>> var z = 7;
      7
>> z = 77;
     x();
     77

Jika scope chain membatasi penggunaan variabel lalu bagaimana jika sebuah function membutuhkan akses terhadap sebuah variabel yang tidak berada didalam scoup-nya? jawabannya adalah closures.

Dengan closures anda dapat memutus rantai scope (scope chain) dan menjadikan sebuah variabel lokal menjadi global.
Contoh #1:

>> function x() {
         var y = "y"; 
         return function z() {
            return y;
         }
      }
>> y
     ReferenceError: y is not defined

>> var w = x(); //closures
>> w()
      "y"

w merupakan variabel global yang didefinisikan dengan var w = x(); sehingga variabel w memiliki value function x(), karena variabel w merupakan variabel global maka ia menyeret x() ke scoup global yang mengakibatkan y dapat diakses tidak hanya dari dalam, tapi juga dari scoup luar.

Contoh #2:

>> var x; 
     function y() {
        var z = "z"; 
        x = function w() { //menjadi variabel global
        return z;
        }
     }
>>y();
     undefined
>>x();
     "z"

Sebuah function baru didefinisikan didalam y() yaitu function w(), namun function baru tersebut tidak menyertakan statement var yang mengakibatkan function w() menjadi global. Pada saat didefinisikan x() berada didalam y() sehingga x() dapat mengakses scope y(). x() akan tetap dapat mengakses y() meskipun ia telah menjadi variabel global.

Contoh #3:

>> function x(arg) { //argumen menjadi variabel lokal
         var y = function z() { 
         return arg; //mengembalikan argumen parent
         };
         arg++; // arg di increment (value nya di tambah 1)
         return y; //mengembalikan value yang sudah di update (increment)
     }
>> var w = x(789);
>> w();
      790

Pada saat menurunkan argumen pada function, argumen menjadi variabel lokal. Anda dapat membuat sebuah function yang mengembalikan function lainnya, yang mengembalikan argumen dari parent.

Penguraian diatas masih belum membahas bagaimana closures pada loop, penggunaan pada getter/setter dan iterator, namun sudah cukup memberikan pemahaman tentang closures pada Javascript.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.