Posts Tagged ‘classes’

Experiment #2: Emulating protected members in JavaScript

Summary : Do you still believe that there are only public, private and privileged members in JavaScript objects? With JavaScript, you never can be sure.

Lego principle

As I might have told you, I think that JavaScript is an amazing language. Even so, I would like to repeat it again. It is the ultimate language for me, and I hope it’s so for you. JavaScript is like a Lego constructor, depending on how you combine different parts, you might get a car, a house or maybe just a pile of crap. Your imagination defines the rules.

This time I’ve discovered some unbelievable combination. It allows you to create and use so called “protected” members in JavaScript. How do I define protected members in JavaScript? As a mixture of both, private and public members, which gives you the possibility to inherit, override and access private members without use of a privileged bridge. If you don’t know what these members are or have just forgotten them, here is a link to refresh your memory. For now, let’s look at an example below :

function Some(...) {
    // defining private member
    var value = 'value';
}

Some.prototype.getValue = function() {
    return value;
};

Code : Scoping issue when adding methods to prototype

As you might have noticed, the code above is broken. Executing getValue function, will throw an exception, because the declaration of getValue is not in the same scope where value variable is declared. To make the code work, function getValue should be declared inside a constructor, hereby becoming a privileged member. This limitation makes it impossible to access the private variables outside the constructor.

The experiment I wrote does allow you to work with the private members outside the constructor, meaning you can add functions to the prototype and expect them to behave as if they are all in the same scope. Sounds cool, right? Actually, it doesn’t look half bad.

Some = Declare({
    _value : 'value',
    getValue : function() {
        return _value;    
    }
});

SubSome = Declare( Some, {
    setValue : function(val){
        _value = val;
    }
});

Code : Declaring class with protected member using prodec wrapper

In the example above there is one protected member _value. It is declared like other public members getValue and setValue, but it is accessed as a private member. Accessing _value variable in the SubSome class shows that the private scope, indeed, “can be” shared. I would like to put extra emphasis on the fact that the protected member is not accessible from outside the object, there is just NO possibility to do that. This means that someObj._value will be unavailable.

I used a declaration wrapper to hide all implementation details ( I love code separation ), but here is the approximately unwrapped code, which will help you to easily “diff” both listings:

Some = Declare();

Some.prototype = {
    _value    : 'value',
    getValue : function() {
        return _value;
    }
}

//Adding inheritance
SubSome = Declare();
SubSome.prototype.__proto__ = Some.prototype; // Note: IE does not support __proto__ convenience
SubSome.prototype.setValue = function(val) {
    _value = val;
}

Code : Declaring protected members with prototype

The code above does the same thing as the first broken example, except that it also consists of SubSome inheritance. The SubSome inheritance is there to show you that you can access protected members declared in a superclass. Consider that the constructor is created by the Declare function and not like usually by function(){}. ( For those who need explanation about __proto__- here is link ) Note, that it’s also possible to share protected functions, not only variables, like in this example.

Internals

I guess you already have plenty of questions concerning the implementation of this experiment. I will not withhold the answers from you and will start explaining all the details right now. If you think that the code is the best source for explanation, I suggest you move at once to the last part of this article or visit a playground.

The first answer is with :) . I was always wondering how private scope could be shared. We have the ability to share “this” scope, by saving it as variable, but we have no way to save a private scope and unroll it somewhere else. In context of “protected” members, we really need to save the private scope and apply it in different places. Even though we can’t do that “officially”, it’s possible to emulate this behavior by using with keyword. I’m sure everyone of you know what with is doing, but everyone is avoiding it, because it’s a bad coding practice. Anyhow, let’s leave prejudice out of this and look at the possibilities with brings us.

var obj = { zork : "Bork" }
with (obj) {
    alert( zork );
}

Code : “With” Nature

This code, is doing exactly what is needed for emulating protected members. It allows you to access obj variables as if they are private variables. Looking from with perspective, the given obj can be seen as private scope. But let’s leave this part for a second and look at the next code.

var s = function(){
    var zork = 'Bork';
    return function() {
        alert( zork );
    }();
}
var fnc = s();
fnc(); // alerts Bork

*Code : Closure nature *

We know that internal closure bla will popup “Bork”, because of the nature of the closures. Now, I will combine both characteristics of closure and with and show what would happen if we create closure inside with. All the variables of obj will be available to the closure, meaning we could manipulate the scope :

var s = function(){
    var obj = { zork : "Bork" }
    with (obj) {
        return function() {
            alert( zork );
        }();
    }
}

var fnc = s();
fnc(); // alerts Bork;

Code : Combining “closure” with “with”

The result is the same, except now, we have our private scope coming from object and not from “var” declaration. This is really the main element of my experiment : Creation of the functions inside with and assigning them to the object. All thanks to the dynamic ability of JavaScript, which allows us to create and bind functions at runtime. Time to see how to apply this closure-with combination to create objects based on their prototype.

We know, that every constructor consists of a prototype object. This object contains almost the full definition of the object. I say almost, because functions can be created inside the constructor, which are not visible through the prototype. Even then, during object creation, it’s possible to walk through the prototype of the object and do things based on some requirements. For example : As you’ve already seen, protected members in my code start with an underscore. Based on this, we can collect all such members and place them inside our protected object. Later we can use this object inside with, so that the underscore members appear as private members.

function Some() {
    var proto = Some.prototype;

    this._protected = {};

    for (var i in proto) {
        if ( /^_/.test(i)) {
            this._protected[i] = proto[i];
        }
    }
}

Code : Creating protected scope object

Scope is built, it’s time to use it :

Some.prototype._value    = 'value';
Some.prototype.getValue = function() {
    with (this._protected) {
        alert( _value );
    }
}

Code : Using protected object to emulate private scope

As you can see, we’ve made the first, yet the most important step of the “protected members” principle. However, there are still a number of issues. To start with, protected scope is available to the outside world, because it’s publicly defined. Further more, it is the requirement for the with keyword in every function where protected scope is presented. These issues leave an implementation footprint in the declaration of the class, which does not look very neat. Both issues are related, meaning that fixing them should be done at the same time.

First of all, we need the technique to hide our protected scope from the public “eyes”. A solution to this would be to use the nature of private members. The protected scope object should be defined as a private member. The only issue in this case that we will be facing the problem described above, namely inability to access private members outside the constructor. A fix for that would be to keep creation of the functions inside the constructor as well. The question is, how? Well, in the constructor we have access to any function and to the object itself, so if we could clone every function of Some object and reassign it, the desired behavior would be achieved.

To clone a function I have to resort to using another “evil” keyword – eval. Because every function exposes its body via toString(), we could evaluate it, at the places we need. Here is clone example :

var fnc = function() { alert('a') ; }
var member = '';
var clone;
clone = eval( "clone = " + fnc.toString() );

Code : Cloning function

Because eval remembers the scope in which it was evaluated ( has access to the member variable), a function can be cloned inside the with statement, having access to the protected scope object. Well, enough talk, it’s time to put all the building blocks together and see the result :

function Some() {
    var proto = Some.prototype;

    var protscope = {};

    for (var i in proto) {
        var member = proto[i];
        if (typeof member == "function") {
            with (protscope) { //adding protected scope 
                // cloning, 
                // cloned function receives automatically the scope correct scope
                member = eval( "member = " + member.toString() );
            }
        }
         
        // doing reassign
        this[i] = member;
        
        if ( /^_/.test(i)) {
            protscope[i] = proto[i];
            // removing protected variables from outside
            this[i] = null;
        }
    }
}

Some.prototype._value = 'value';
Some.prototype.getValue = function() {
    alert( _value );
}
Some.prototype.setValue = function(val) {
    _value = val;
}

Code : Result of all the effort – creating protected members

If you are familiar with JavaScript the code should be fairly self explanatory. To get a better feeling for protected members, as I mentioned earlier,I’ve created a playground for you. I did not cover all parts of the declaration wrapper here, such as dealing with this keyword, using super classes, etc. If you are interested, grab the source code and enjoy.

How much does it cost ?

What actually is a price of protected members? First of all – Speed. I haven’t performed any benchmarks, but by analyzing the code I can tell you that this emulation will run slower than normal creation of objects. Using with together with eval for every object member will stall the runtime. Secondly – memory consumption. Using a set of functions for every instance will eat up more memory in comparison to the prototype based instances.

Nevertheless, if the speed does not play a big role and you see advantages in using protected members you could adopt the code for your own needs.

JavaScript without “new” and “this”keywords

“If you don’t like ‘this’, try Zet.js” (c) M.Nemisj

Plot: This article is about an experiment of avoiding “this” and “new” keywords in JavaScript and about the results of it.

Harmful “new” keyword and replacement for that

There are different debates flying around the internet about the safety of using “new” keyword in JavaScript. It’s all started when Douglas Crockford stated that “new” keyword can be harmful and that he doesn’t use it any more in his code. In replacement for that Douglas Crockford proposed factory functions. In public they also called sometimes Function OOP or Module pattern.

I really like dynamic nature of JavaScript, so this solution excited me. The fact that in JavaScript there is always something new to found or new to learn brings me esteem to the JavaScript language.

The only thing which I considered to be not elegant in this solution, was the inheritance paradigm. It gave me the feeling that code is too “custom”, too “hardcoded”. To fully understand what I mean, you should see it yourself:

This is how normal factory function looks like :

var User = function(){
    var privatMethod = function(){
        alert('hello');
    }

    return {
        sayHello : function(){
            privateMethod();
            this.done = true;
        }
    }
}

In the code above we created declaration of the User class. Creation of the new User instance is possible without “new” keyword:

var user1 = User();
var user2 = User();
Now, let’s imagine that we would like to create sub-class of the User. Using inheritance in this pattern is not trivial when it concerns methods overriding, but it still can be achieved

var SubUser = function(){
    var user = User();
    var oldMethod = user.sayHello;

    user.sayHello = function(){
        oldMethod.apply(user, arguments);
        user.done = false;
    }

    return user;
}

As you can see, the declaration of subclass differs from its super-class. In my opinion this makes code less readable, and more fragile. Moreover there is too much logic involved inside the declaration of the class itself( like “apply” logic or keeping track of instance scope), so code does not become self-expressing to the reader.

That’s why my idea was to make library which would make some unified structure for Class declaration in Functional OOP style with inheritance support. There are some libraries which support Functional OOP style, but all of them, which I’ve seen are using “new” keyword. Then I’ve started with experiments and ended up with the library which is full of experiments or simply Zet.js. About all of the interesting points and experiments you can read bellow in this post.

First seeing, then believing

Before reading all this text bellow, I guess it can be interesting to see how class declaration with Zet.js looks like. Let’s redeclare SubUser :

Zet.declare('SubUser', {
    superclass : User,
    defineBody : function(that){
        Zet.public({
            sayHello : function(){
                that.inherited(arguments);
                that.done = false;
            }
        });
    }
});

Scope substitution & why no “this” usage.

Working with different people, reading articles on the net, brings me to the idea, that “this” keyword is one of the most complex concepts in the JavaScript. Especially when new developers find out that “this” can point to different scopes. Such instability of “this” keyword brings a lot of confusion, especially to the people, who came from static languages like Java or C#. First and most valuable aspect of Zet.js is, that it provides a solution to stop dealing with cumbersome “this” variable.

There are different ways in which “this” variable can be substituted. I think, it’s essential to know global/important cases, when it can occur. People, who are not interested in causalities can skip this chapter and start reading about implementation details.

As I told, by knowing most used cases it’s much more easier to identify the generic solution. One of the most important cases in my list is accessing of “this” variable from within anonymous function. Let’s look at standard non working example bellow.

User.prototype.delayMe = function(){
    setTimeout(function(){
        this.someFunction();
    },100);
}
Since “this” variable inside anonymous function points to the global scope, the code will throw error, because someFunction is undefined. I guess, this situation happened to most of us, including me. At the time when I only started with JavaScript, my attempt to fix this was to assign function to the variable and then execute it.
User.prototype.delayMe = function(){
    var someFunction = this.someFunction;
    setTimeout(function(){
        someFunction();
    },100);
}
Perhaps, code looks logic and normal, and in some situations it may work, but it’s still not working code. The problem is that as soon as someFunction will try to access “this” variable inside of it, code will break. The reason stays the same. Function “someFunction” is called as anonymous, so “this” variable will point to the global scope.

To help JavaScript developers, most frameworks and libraries offers helping functions, like “bind” (in jQuery) or “hitch” (in Dojo) to use. They help to keep correct scope at the moment of the execution.

User.prototype.delayMe = function(){
   var someFunction = dojo.hitch(this,'someFunction');
    setTimeout(function(){
        someFunction();
    },100);
}
Although we have now support from libraries, there are another two cases which can lead to scope substitution. Take notice that one of them is only valid, if instances are created with “new” keyword.

  1. Instantiate class without “new” keyword.
  2. Using apply or call API calls

I will not explain first one, since the Functional OOP prevents this kind of bugs by default, but let’s check the second one.

Intentionally substitute scope can be done through call or apply API calls. By using one of this it’s possible to make “this” aim at any JavaScript object. In some situations this can be useful (hitch and bind are based on this), but also it can lead to unpredictable results.

After all this theory material it’s time to see what Zet.js proposes.

Protecting “this” with “that”

To protect “this” variable from pointing it to some-where-we-do-not-know, Zet.js prevents usage of it. Instead Zet.js forces developers to use “that” variable. This variable is available from the begin of the instance life-cycle and always points to the correct scope.

Mature JavaScript developers knows, that “this” variable can be assigned to anything(caching it). Zet.js passes “that” to the factory function at the moment of execution and it stays in the private scope of the instance. Because private scope is always available to the body of the instance, developer always have the correct value of “this” in hands.

I also want to notice that, by having such manner of declaring classes, all the private functions inside the class also automatically have the scope to the object instance. This means, that there is no more need in doing extra work like privateFunction.call(this); to access public variables or functions from the private scope.

Let’s look at the example above one more time.

Zet.declare('SubUser', {
    superclass : User,
    defineBody : function(that){
        Zet.public({
            sayHello : function(){
                that.inherited(arguments);
                that.done = false;
            }
        });
    }
});
As I mentioned already class declarator passes “that” to defineBody factory function, which points already to newly created object.

Strange Zet.public function

I guess you’ve already noticed strange Zet.public declaration in defineBody factory. This is another experiment of mine. It is not usual to see such way of declaring things, but it is made to create logical split between functions, which are included for private purpose and public functions. Further it brings totally no functionality into the object, pure for experiment.

In case you think, this is REALLY useless, Zet.js supports also return statement as normal Functional OOP declaration does.

Zet.declare('SubUser', {
    superclass : User,
    defineBody : function(that){
        return {
            sayHello : function(){
                that.inherited(arguments);
                that.done = false;
        };
    }
});
Moreover Zet.js also supports style for developers who has been used to the functional style in “normal” JavaScript Classes:
Zet.declare('SubUser', {
    superclass : User,
    defineBody : function(that){
        that.sayHello = function(){
            that.inherited(arguments);
            that.done = false;
        }
    }
});
Except that in such situation “that” variable should be used instead of “this”.

Functional OOP/Module pattern pitfall.

One of the strong arguments for people not to use Functional OOP is the fact that the instanceof functionality is not working correctly. Because factory function creates every time unique object instanceof will always return false. I’ve seen some solutions to fix this, but they remain using “new” keyword internally in the declarator itself. As I told already before, Zet.js is truly “new”less, so I could not use any of the solutions which I’ve seen.

Instead Zet.js extend every instance of the object with own instanceOf possibility. Passing class constructor to this function will return false/true depending if the constructor belongs to this object or to its superclass. Thus, expressions bellow will return true.

subUser1.instanceOf(User);
subUser1.instanceOf(SubUser);
To make instanceOf more universal, I’ve included global instanceOf possibility. Which works with for normal objects, Zet objects and with fixed instanceof String case :
// Zet instances:
Zet(User).instanceOf(User) //return true;
Zet(subUser1).instanceOf(User) //return true;

// normal instance Zet([]).instanceOf(Array) // return true;

// String instanceof fix "some-string" instanceof String //return false Zet("some-string").instanceOf(String); // return true

InstanceOf of Zet.js can be also used as drop-in-replacement for native instanceof.

Is there something normal in Zet.js?

Yes, besides strange .public syntax, forced “that” usage and other experimental stuff, Zet.js also has some “normal” facilities, like :

  • Support for Inheritance
  • Separate “initialize” call
  • Declaring classes through Namespaces
  • Simple loggin facilities
  • Inner constructor function
  • CommonJS Modules API support

This article is big enough, so I will not describe here in details  all of the listed things. If you are interested you can find all the explanation inside README file on github.

Update : As noted by Tim Caswell it’s better to name your factory functions with a “new” prefix to indicate that such constructor should be called without new keyword, for example : var person = newPerson(); Also it’s important to understand that each instance of such factory has a big impact on the memory, since it consists of own copy of all the functions of the class.

Zet.log("That's all");
Download zet.js in zip

Return top