Friday, February 18, 2011

JavaScript Closures

Closures are one of the most powerful features of the JavaScript language, and also one of the least understood. Simply put, a closure is an object that retains access to the lexical scope in which it was created. Remember that in JavaScript, functions are first class objects, they can be assigned to variables, passed as arguments etc.


Take the following example:


        function myFunction() {
            var i = 0;
            return function () {
                alert(++i);
            };
        };

        var myFunction2 = myFunction(); //myFunction is now out of scope
        myFunction2(); //displays 1
        myFunction2(); //displays 2
        myFunction2(); //displays 3


What happened? The function returned by myFunction retains access to the local variable i - this is a closure. JavaScript maintains not just the returned function, but a reference to the environment in which it was created - including all the local variables in scope at that time.


So, why is this useful? Well, one excellent use is encapsulation, allowing an object to expose a public API whilst keeping it’s internal data and functionality private.


Consider this example:


        function myObject() {
            var i = 0;

            function increment() {
                return ++i;
            };

            function decrement() {
                return —i;
            };

            return {
                PlusOne: function () {
                    alert(increment());
                },
                MinusOne: function () {
                    alert(decrement());
                }
            };
        };

        var myObjectInstance = myObject();

        myObjectInstance.i = 1; //fails, private variable
        myObjectInstance.increment(); //fails, private function
        myObjectInstance.PlusOne(); //displays 1
        myObjectInstance.PlusOne(); //displays 2
        myObjectInstance.MinusOne(); //displays 1


Our MyObject function has a locally-scoped variable “i”, and two locally-scoped functions, “increment” and “decrement”. The return value is an object (defined with object literal notation) that defines two functions, “PlusOne” and “MinusOne”. These functions are public, but they access the private functions “increment” and “decrement” via the closure provided by myObject’s context. This is starting to look a little like private methods and variables in classical OO…


Taking it one step further, we can introduce a variation on the classic GoF singleton pattern by making the function execute and return immediately with the following syntax:


        var myObject = (function () {
            var i = 0;

            function increment() {
                return ++i;
            };

            function decrement() {
                return —i;
            };

            return {
                PlusOne: function () {
                    alert(increment());
                },
                MinusOne: function () {
                    alert(decrement());
                }
            };
        })();


Our object is now instantiated and ready to use:


        myObject.PlusOne();
        myObject.PlusOne();


This is generally referred to as the JavaScript Module Pattern, and attributed to Douglas Crockford. For a concise synopsis: http://www.yuiblog.com/blog/2007/06/12/module-pattern/. It’s a very useful pattern, lending itself to modularization of JavaScript code.


There are pitfalls, some of which I’ll go into in future posts. However, carefully used closures lend themselves to clean, powerful, maintainable JavaScript code.


1 comment:

  1. When getting into a recreation, players can immediately see the vendor, interact with them, and also with other players on the table. Want to get started gambling on-line, however solely if it is with precise stay dealers and players? Many individuals seek out on-line stay casinos since it mimics the general really feel of being in a real casino. Live vendor casino games add an additional dimension of realism to on-line play, adding actual human interplay and an unbeatable environment to variety of the} world’s most popular games. Live vendor games usually pull in players who wouldn’t normally be interested in on-line slots, which could be extremely valuable to your corporation. By enjoying in} stay casino games in your native foreign money, you can make make|you might make} quicker, simpler deposits and withdrawals, whereas 먹튀검증 additionally avoiding pesky exchange charges.

    ReplyDelete