About nested functions.

Note: this was intended as a response to this tutorial: http://net.tutsplus.com/tutorials/javascript-ajax/stop-nesting-functions-but-not-all-of-them/

and specifically, to this comment:

http://net.tutsplus.com/tutorials/javascript-ajax/stop-nesting-functions-but-not-all-of-them/comment-page-1/#comment-383621

It was posted here because it did not appear on the comments on nettuts after I submitted it. No error was given either.

The reply starts here:
==================================================
I think the problem you are having is in understanding how stuff works in the machine. Part of it is because the explanation of why they are equal or not is a bit incomplete.

When you declare a function like:

var f = function(){}

an object function is created somewhere in memory and then f is linked to that piece of memory that contains the actual function. So, consider this:

var f = function (val){alert(val);}
var f2 = function (val){alert(val);}

Both functions are the same to you. I mean they both do the same thing, and their code is the same. However, for the computer this functions are different just because they are stored in different places in memory.

When the interpreter finds the firs line, it creates a function object and stores it somewhere in memory. Then it moves onto the next line, and finds another function that has to be created. This functions is exactly the same, in content at least, as the one that was just previously created, but the interpreted does not care about it. It simply knows that it has to create another function object and store it in memory. Then when you do this comparison

f === f2

this is false, because the engine sees that you are comparing 2 different bits of memory, so it cannot be the same thing. If it were, it would be store in the same place rather than in different places in memory.

Now it gets interesting. What if we do this:

f = f2;

What happens here? well, we are basically braking the link between f and the first memory declaration and now we are linking f to the function object to which f2 is linked. This is very powerful stuff.

Before I go deeper into why this is powerful, let me correct something that I think is wrong.

If you look at figure 2, this is not completely true. What you really have is this:


|           Jeremy             |
|---------------------------- |
| firstName = "Jeremy" |
| lastName = "McPeak"|
| getFullName              |

And the same for Jefferey, but with the difference that getFullName does not point to it’s own function, but to the function in the prototype object. This is essential to understand because once you know this, you can extend an object, and overwrite it’s methods like this:

var jeremy = new Person("Jeremy", "McPeak"),
    jeffrey = new Person("Jeffrey", "Way");
jeffrey.getFullName = function(){
     return this.firstName + " " + this.lastName + " is awesome!";
}

EDIT: As Jeremy demonstrated in one of his fiddles linked to in his comment to this post, there is really no getFullName method in the object. I was wrong here. What really happens is that a new method is added to jeffrey, and this method takes presendece over the one in the object’s prototype.

This might not be the best example, but there really are cases where you want to do something like this.

If you stick to figure 2, that assumes that changing getFullName will change the method for all Person Objects, where as if you see the figure I created in this comment, you can easily realise that you are just changing the function that jefferey.getFullName links to rather than that of all Person Objects.

Now, back at why this is powerful stuff. I’m going to extend the last example in the tutorial and demonstrate how you can still have “private” properties without the performance hit.

Lets copy here the example just for reference:

function Foo(paramOne) {
    var thisIsPrivate = paramOne;

    this.bar = function() {
        return thisIsPrivate;
    };
}

var foo = new Foo("Hello, Privacy!");
alert(foo.bar()); // alerts "Hello, Privacy!"

So, the benefit here is that you cannot change the value of the private variable.

var foo = new Foo("Hello, Privacy!");
alert(foo.bar()); // alerts "Hello, Privacy!"
foo.thisIsPrivate = "hey";
alert(foo.bar());//still hello, Privacy

the private variable is simply not accessible to you.
I heard in the video that the author said that the user could just go in the file and change the private to not private. This implies that private or not private doesn’t matter in javascript because someone can just go into the file and change the code. This is WRONG!

The real value of private variables is that other code in the page, code that might have been inserted by an attacker, or by some other script in the page, cannot modify the private variables. It has nothing to do with whether a person can modify your code or not. I was surprised to hear that because I consider it to be newbie mistake.

If you don’t know what I’m talking about, start the video at around minute 25:30 and listen from when the author talks about someone accessing the code.

And there is also this:

“Until JavaScript fully supports private properties and methods, wouldn’t you rather have more efficient and performant code than privacy? The correct answer is: yes!”

The correct answer is NO!, for security’s sake, you cannot really be telling people that performance is more important than security, and the only reason you want private variables is security. How did that quote find it’s way out into the open!!

The truth is you want private methods and variables, even if it costs you a little performance. The good news is that it does not have to.

Let’s look at a slightly more advanced and better ways to do it.

function foo(param1){
    this.constructor(param1);
}

foo.prototype = function(){
    var private;

    function c(p){
        private = p;
    }

    function b(){
        return private;
    }

    return {
        constructor : c,
        bar : b
    }
}();

var c = new foo("private, I am");
alert(c.bar());

This code is just a little bit more complex, but it is more robust, secure and adds very little overhead. There is still a prototype, no functions are declare inside foo, or any other function that would get executed more than once, but it has a little error. Private is private, but not really.

The idea behind private variables is that they should not be modified after they have been set. At least not from outside the object. In the tutorial we are taught to use _ (underscore) to “signal” other developers that that variable is supposed to be private. This would be nice in a world where you can leave your car with the doors wide open and the keys inside without worrying about robbery.

The truth is that an attacker can easily change the value of the variable even if we said, hey, this is supposed to be private. And that my friends, is a bad thing.

Now, to be fare, this code I just showed you, suffers from the same problem. An attacker cannot directly access “private” (the variable), but they can easily change it without having to access it directly. Check this out:

function foo(param1){
    this.constructor(param1);
}

foo.prototype = function(){
    var private;

    function c(p){
        private = p;
    }

    function b(){
        return private;
    }

    return {
        constructor : c,
        bar : b
    }
}();

var c = new foo("private, I am");
alert(c.bar());
c.constructor('not really');
alert(c.bar());

As you can see, by calling constructor again, we are able to change the value of private, and this is not supposed to happen. Happily, solving that problem is just one line of code away. Check this implementation:

function foo(param1){
    this.constructor(param1);
}

foo.prototype = function(){
    var private;

    function c(p){
        private = p;
        this.constructor = null;
    }

    function b(){
        return private;
    }

    return {
        constructor : c,
        bar : b
    }
}();

var c = new foo("private, I am");
alert(c.bar());
c.constructor('not really');
alert(c.bar());

by removing the link from constructor to the c function, the attacker has no access to private, and private becomes, you guessed it, private.

There is more stuff that can be done with this simple pattern, and I think there are better ways to solve the performance problems suggested in the tutorial than those suggested in the tutorial. Especially because nested functions are powerful if you know how to use them. If you simply neglect nested functions, you are throwing away a big chunk of javascript’s power.

Now, just to clarify one thing, or maybe not. When you develop code, think beyond the user. The reason why this:

“Until JavaScript fully supports private properties and methods, wouldn’t you rather have more efficient and performant code than privacy? The correct answer is: yes!”

Is so wrong, is because it assumes the only danger when it comes to javascript private variables comes from other developers using your code, but that is not true. The real danger comes from people who are not developing the same site accessing your code and private variables. You want those variables to be private for a reason, not just because it is cool. It makes no sense to have something that looks like private, that people know is supposed to be private, if that thing is not really private. I mean, that is the source of most security problems in javascript, and anyone who tells you that performance is more important than security is cruelly lying to you, intentionally or not, and is setting you up for disaster.

On the other hand, if and attacker has access to your files to modify them, performance is your least concern. You are already screwed.

About these ads

12 thoughts on “About nested functions.

  1. Hi there,

    Great article showing how to keep private variables. I see the module pattern being used a lot and I was wondering if it suffers from performance, I created a test page http://jsperf.com/nested-named-functions/3 let me know what you think or what alternative I should use for module pattern if it’s too slow

  2. Great article, thanks for sharing an alternative that still has private properties etc.
    What are your thoughts on the popular use of the Module Pattern? Is it good enough performance wise?

    I put up a test case where I compare module pattern vs nested functions etc

    http://jsperf.com/nested-named-functions/3

    I noticed the performance varied from browser to browser, which makes me thing what is the “best” solution?

    Regards DotnetShadow

    • I see no problem with the module pattern. Most of the time it is a matter of using the right tool for the right job. And one thing you should remember about performance: premature optimisation is as bad as no optimisation. Performance is not a matter of tuning functions, but about tuning entire applications, and for that you need to have the whole thing done, identify your bottle neck and fix it. I’m not saying write reckless code without worrying about performance until you are done, I’m saying, write good code, as good as you can, then identify your bottlenecks, then optimise.

  3. There is nothing incorrect. Your first assertion that figure 2 is not completely true is wrong. It is true. jeremy does not have its own getFullName() method, as evidenced by http://jsfiddle.net/Pfkua/1/.

    It is true that you can override members defined on the prototype, but the question is: should you? The answer is, and has always been: No!! Person is a data type, and as such, all Person objects are expected to have the same exact behavior. By overriding jeffrey.getFullName, you have broken the behavioral commonality between jeffrey and all other Person objects; you’ve taken predictable code and made it less predictable. Just because you can doesn’t mean you should. The acceptable pattern for modifying a data type is to create a new data type (AwesomePerson in this case), inherit Person, and overwrite AwesomePerson.prototype.getFullName.

    As for security vs performance, there are situations where security would be better than performance, but I still stand by my statement in general: performance > security by privacy (until true privacy is added to the language).

    Lastly, your solution for privacy + prototype only works for singletons (see http://jsfiddle.net/ghnsy/), in which case, there are much better singleton patterns.

    • It all depends on what you are doing. Just because there is a patter doesn’t mean you should always use it. Besides, I’ve always found it a bit naive to try to implement patters from class-based OOL and bring them into a language that is based on prototypes.

      My solutions is not definitive, I know, it has holes in it, but it is easier to patch then than with your solution. For example, in real world code I would not use the operand new. I would build an object, not a “class”. You cannot instantiate an object, and you would not be able to modify its internal variable. The point is, it is possible to create private variables, and that will always be better than whatever performance you can win by neglecting nested functions.

      Now, don’t get me wrong. I see the point you are making on the tutorial, and I agree. You should avoid nested functions if necessary, but you should not just neglect them completely. The performance gains not always outweigh the security risks, and that is my point. I see no problem with that, and quite frankly, if you think that is never the case, then I’m sorry for you pal, but you are letting your code vulnerable, more than it should be.

      • I think you’re confused. I haven’t suggested using OOP features from other languages. Quite the contrary, actually. Inheritance isn’t foreign in JavaScript; it’s achieved by chaining prototypes. JavaScript OOP 101.

        We’re not talking about singletons; we’re talking about multiple objects with the same interface and behavior. Yes, you can create an object on its own, but if you want multiple objects with the same interface and behavior, it is far more efficient to define a data type (in other words, a constructor function) and create objects from it.

        I know full well that my objects can be tampered with–I thought that was obvious. I’m what you’d consider a JavaScript purist, and I find it funny you find the naivety in trying to implement patterns from other OOP languages, such as privacy, but yet champion it.

      • I am not confused. I know what I’m talking about. I have written about OOP in javascript, I know how it works, and I know how it does not. I know about prototypes, about pseudo classes and about objects.

        I am not saying inheritance is foreign to the language. What is foreign, however, is the concept of classes. You, as a javascript purist should know it. And what you are doing is trying to emulate classes.

        And not, we are not talking about singletons, but neither are we talking about multiple object. We are talking about nested functions (read the title of the post) and about privacy. I think you are confused in the topic of this discussion.

        I’ve already demonstrated that I’m capable of admitting my mistakes, the question is are you?

      • I’m not trying to emulate anything. The ability to define data types has been part of the language since JavaScript 1. It’s not foreign in the slightest. Shoot, Object, Boolean, String, Number, Array are all built-in data types. I have no problem owning up to my mistakes, but this isn’t one of them.

        We’re on this discussion because of the topic of nesting method definitions inside a constructor function. About the only reason you would have a constructor function is to create multiple objects with the same interface and behavior. Your tangent of how you create objects in the real world prompted me to throw in a tangent of my own. For that, I will say I was wrong and apologize.

      • It seems we won’t agree on the objects part. I would say neither of us is wrong, just different style. When I talked about your mistakes, I was talking about the privacy. It is clear we won’t agree on that either, and that is OK. Debate is healthy, it makes us see the world from a different point of view. I still believe that it is wrong to simply neglect nested functions based only on performance without considering the security risks. That has been my primary point all along.

        We talked about other matters, it is true, but my primary point is that sometimes it is OK to use nested functions if it makes our programs more secure.

        And, I think now I can only say thanks for engaging in this conversation. It is little debates like this that makes ordinary days extra ordinary. Peace.

    • OH, and yes, you are right about the object not having a getFullName method. I updated the post. Thanks for pointing it out.

  4. There appears to be a flaw in your suggested implementation: the supposedly private variable isn’t private, but shared between all foo instances:

    function foo(param1){
    this.constructor(param1);
    }

    foo.prototype = function(){
    var private;

    function c(p){
    private = p;
    this.constructor = null;
    }

    function b(){
    return private;
    }

    return {
    constructor : c,
    bar : b
    }
    }();

    var c = new foo(“private, I am”);
    var d = new foo(“or not so much.”);
    alert (c.bar());

    • Yes, it was pointed out before. That can be fixed though. When i have a chance i will update the post with an implementation of how it could be fixed.

Comments are closed.