Wednesday, October 30, 2013

Javascript OOpseseses

Yes, well I am confessing that I enjoy working with JavaScript for much the same reasons as Mr. Douglas Crockford does.  I was attempting to do a little OO coding, trying to basically specify an interface with a base class and inheriting from that class for various implementations of the interface.
This blog I found was quite helpful to me but still vague in how to properly use it.
So here is some short code I made up that convinced me of the right way to do inheritance.
<!DOCTYPE html>
<html>
<head>
  <title>Playing with OO javascript</title>
<script type="text/javascript">

// see http://javascript.crockford.com/prototypal.html
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
// Usage:newObject = Object.create(oldObject);

function createParentClassInstance() {
    var o = {};
    o.item1 = 'Parent says: hi.';
    o.item2 = 'I\'m the parent';
    return o;
}

function createChildClassInstance() {
    var o = Object.create(createParentClassInstance());
    o.item2 = 'I\'m the child';
    o.item3 = 'Child says hi.';
    return o;
}

function out(s) {
    document.body.innerHTML += s;
}

function PageLoad() {
    var parentInstance = createParentClassInstance();
    var childInstance1 = createChildClassInstance();
    out(parentInstance.item1 + '<br>');
    out(parentInstance.item2 + '<br>');
    out(parentInstance.item3 + '<br><br>');
    out(childInstance1.item1 + '<br>');
    out(childInstance1.item2 + '<br>');
    out(childInstance1.item3 + '<br><br>');
}
</script>
</head>
<body onload="PageLoad();">
</body>
</html>
Note how we hide the definition of the objects within a clearly defined constructor function.  Inheritance is controlled by the class factory so things become clear what they mean and its not easy to just throw objects together in random inheritance trees.
If would also seem that multiple inheritance could be done this way by simply cascading the instance creation functions to make a multi-generational inheritance structure.
I am hoping that Dr. Crockford will have a chance to comment on this blog and correct me if I am wrong here. 

2 comments:

  1. Yeah, that seems reasonable. You'd definitely need to be careful about your definitions on the createXInstance() functions, but that seems like it would work. Did you see this one? http://webreflection.blogspot.com/2009/06/wait-moment-javascript-does-support.html

    I like your encapsulation better, though.

    ReplyDelete
  2. Good note. I do like my form better because it adds a little naming convention to help shore up what is meant by the code. JavaScript is so loose you can tie yourself in knots and get confused - which I still am. The article you mention goes into multiple inheritance which can be done but what I think a reader needs to clearly see is the inheritance chain of any object and because the class factory functions are clearly named create... one can quickly search the js code for the parent class definitions.
    This idea of just throwing new elements into a class after the fact with .prototype is just scary to me.
    Also I am still unclear how an instance of a function() varies from the function itself. My convention forces just using instances and further simplifies the mire.
    I hope Crockford finds time to glance at this - if he approved, I know I am on a good track.

    ReplyDelete