0

I'm trying to wrap my head around anonymous and named functions and I have this Javascript code here:

travelNode = min = function(travelNode) {
      console.log(travelNode);
      if(travelNode.left === null) 
           return travelNode;
      else 
           return min(travelNode.left);
}(travelNode.right);

When I try and run this block, I get a ReferenceError: min is not defined. However, when I change the code to this:

travelNode = function min(travelNode) {
      console.log(travelNode);
      if(travelNode.left === null) 
           return travelNode;
      else 
           return min(travelNode.left);
}(travelNode.right);

and it works just fine.

Obviously, the first one uses anonymous functions and the second a named function. However, why does the second one work but the first one doesn't? How would I fix the first one?

Edit: Here's the entire code block -

delete: function(data) {
        var deleteHelper = function(travelNode) {
            if(travelNode === null)
                return null;
            if(data < travelNode.data)
                travelNode.left = deleteHelper(travelNode.left);
            else if(data > travelNode.data)
                travelNode.right = deleteHelper(travelNode.right);
            else {
                if(travelNode.right === null)
                    return travelNode.left;
                else if(travelNode.left === null)
                    return travelNode.right;
                travelNode = min = function(travelNode) {
                    console.log(travelNode);
                    if(travelNode.left === null) 
                        return travelNode;
                    else 
                        return min(travelNode.left);
                }(travelNode.right);
            }
            return travelNode;
        };
        this.root = deleteHelper(this.root);
    }
2
  • Where are travelNode and min declared? Can you post a demo to reproduce the problem? Commented Aug 25, 2015 at 6:19
  • var min; travelNode = min = function(travelNode) { Commented Aug 25, 2015 at 6:21

1 Answer 1

3

var g = function f() { ... } will scope f inside the function (so it is undefined outside it); it will be assigned to g outside it (which has scope over the insides of it). As a result, you can call the function f inside, and g both inside and outside. f is safe from tampering, since it only has value in the closure; while g can be redefined, potentially breaking your code.

In your second example, min is defined inside the function (but not outside it); since you use it inside but not outside, everything works.

In your first example, you make an anonymous function. Then you invoke it with (travelNode.right). The function executes, and breaks (since min is not yet assigned). If the function were to complete without error, the return value would have been assigned to both min and travelNode (just like y = x = Math.sqrt(4) assigns 2 to x and also y after evaluating Math.sqrt).

You could use parentheses, and make it work:

travelNode = (min = function(travelNode) {
      console.log(travelNode);
      if(travelNode.left === null) 
           return travelNode;
      else 
           return min(travelNode.left);
})(travelNode.right);

Here, you construct an anonymous function, assign its value to min, then invoke it; since min is assigned and in scope, it still works.

Arguably, your second approach is the best, given that you only use min from inside; it also has an added benefit for debugging, since the function will not show up as anonymous in stack traces.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.