Ad
  • Custom User Avatar

    How does this work?

  • Default User Avatar

    Basically, closures just mean that the function is always going to have access to the variables of the scope in which it was defined (see the get/set example I gave above). Data protection, like in this instance, is useful when the data in an outer scope is going to change (e.g. in a loop or when certain events happen), and you don't want it affecting some particular part of the function.

  • Custom User Avatar

    @edsel: No worries! Happy to help.

    It's good for certain things, but it's kind of a pain the butt to set up for every little thing. Plus there's probably some kind of memory or performance overhead to using this all over the place. Also, it's actually fairly rare you want to store some value that will never change...

    So I'd say it's good in specific cases, but those are pretty few and far between.

  • Custom User Avatar

    Wow! Thank you so much, jacobb and wthit56! This was incredibly helpful. I really appreciate you giving me such thorough explanations, and examples. Y'all are awesome!

    As a follow-up question: is it best practice to "protect" your code by using closures, or is it just something that is useful for certain specific instances?

  • Default User Avatar

    In short, it's a method to define the scope of variables when functions themselves are used as variables. Understanding the var statement is key. I definitely like to analogize it to OOP when explaining it.

    Recently, more traditional classes, let statements and fat-arrow functions were added. They kind of break the pattern with var statements and the this variable.

  • Custom User Avatar

    As @jacobb said, in the Classical pattern this is something akin to a private variable. But don't worry if you don't know anything about Classical OOP. I've left that behind a long time ago, and JavaScript works just fine for me. ;D

    My attempt at an explanation:

    When a function is created (new Function("arg1", "arg2", "/* body */") or function(arg1, arg2) { /* body */ }), any variables it can "see" at that moment are kind of bundled into the function.

    // So...
    var outer = "outer";
    
    function f() {
      var inner = "inner";
      inner === "inner"; // The `inner` variable can be seen,
      // as it was made within the function.
    
      outer === "outer"; // The `outer` variable can also be seen from here.
      // This is the concept of "scope".
      // A function can see all the variables inside it,
      // as well as those within its parent scope.
      // `Outer` is within the parent scope,
      // so it is bundled in with the function.
      // The function is said to "close over" any variables within its scope.
      // The variables are then said to be within the function's "closure".
    }
    
    outer === "outer"; // From here, the outer variable is in the same scope.
    
    inner === undefined; // But the variable created within the function
    // cannot be seen, as it's in a different scope.
    

    Let's go back to the solution. When you call var its = always("on"). You get back a function. If you call that function its(), you get the original value "on". (Arguments are just a special kind of variable).

    The thing is, there's no way of changing that value from the outside. Nothing outside of the function that created it has direct access to the n variable. The only way of reading the variable's value is to run that function.

    This means that other code on the webpage or node server or what-have-you cannot mess with your object values. You are able to have full control over which variables on the object can be changes and how.

    If you have any further questions, I'd be happy to help you with them!

  • Default User Avatar

    In an analogy with OOP, the outer function is kind of like a class constructor, and the inner function is kind of like a method and the variable n is kind of like a private variable.

    Here's an example that uses closures in a way that's more analogous to OOP.

    function product(name, price) {
      var companyName = 'ACME';
      return { 
        getCompanyName: function () { return companyName },
        getName: function () { return name },
        getPrice: function () { return price },
        setPrice: function (x) { return price = x }
      }
    }
    widget = product('widget', 2);
    widget.getCompanyName(); // 'ACME'
    widget.getName();        // 'widget'
    widget.getPrice();       // 2
    widget.setPrice(5);      // 5
    widget.getPrice();       // 5
    

    So if you don't want your data to change, you can protect it with a closure like that.

    Also, you can look at pages 37-39 in Javascript: The Good Parts for some other examples.

  • Custom User Avatar

    Hi, newbie here. I am wondering what would be the purpose of something like this? I saw someone mention closures in the discussion, and I looked those up, but I was hoping for a practical example or two. My knowledge is very limited, so please be as explicit as possible. Thanks!

  • Custom User Avatar

    Thank you for the kata, like the different ways it is solvable!

  • Custom User Avatar

    maybe it has multiple solutions?

  • Custom User Avatar

    Hi, got the same issue. my solution seems valid. did you solve it already?

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    If one would check on length of the two words and the existance of the first index of a letter then it will past the tests.
    The test given below would cover that path.
    Test.expect(!isAnagram("ab","aa"));