Delegation vs Inheritance in JavaScript

When asked what he might do differently if he had to rewrite Java from scratch, James Gosling suggested that he might do away with class inheritance and write a delegation only language.

Using inheritance as a vehicle for code reuse is a bit like ordering a happy meal because you wanted the plastic toy. Sure a circle is a shape and a dog is a mammal – but once we get past those textbook examples most of our hierarchies get arbitrary and tenuous – built for manipulating behaviour even as we pretend we are representing reality. Successive descendants are saddled with an ever increasing number of unexpected or irrelevant behaviours for the sake of re-using a few.

Delegation is a technique that promotes code reuse by allowing runtime function invocation in the context of a specific instance – regardless of the hierarchical lineage of instance and function. JavaScript has excellent support for Delegation in the form of call and apply which lets us inject an object into the this value of any function. This permits unfeterred code sharing, free from the constraints of unwieldy, unnatural and overly complex hierarchies.

I’m going to demonstrate, by way of a use case, how call and apply can promote a clean, functional approach code to re-use. Then I’ll discuss how the ES 5 specification enables re-use of built-in functions by formalizing the concept of generic functions.

Custom Function Delegation

Suppose we need a Rectangle object for a drawing app. Lets create it the old fashioned way using new and constructor.

var Rectangle = function(left, top, length, width, options) {
	this.left = left;
	this.top = top;
	this.length = length;
	this.width = width;
    if (options) {
    	this.color = options.color;
    	this.border = options.border;
    	this.opacity = options.opacity;
    	//... etc.
    }	
}

var myRectangle = new Rectangle(10, 10, 30, 20, {color:'#FAFAFA', opacity:0.7});

 
We’re also going to need to know if the rectangle overlaps with another. We’ll add this function to the prototype:

Rectangle.prototype.overlaps = function(another) {
	var r1x1 = this.left,
	    r1x2 = this.left + this.width,
	    r1y1 = this.top,
	    r1y2 = this.top + this.height,
	    r2x1 = another.left,
	    r2x2 = another.left + another.width,
	    r2y1 = another.top,
	    r2y2 = another.top + another.height;	    

    return (r1x2 >= r2x1) && (r1y2 >= r2y1) && (r1x1 <= r2x2) && (r1y1 <= r2y2);
}

myRectangle.overlaps(myOtherRectangle);

 
Now suppose elsewhere in our app we have a dashboard which renders a bunch of dashlets. We would like to know whether these dashlets overlap one another. We could use inheritance – have Dashlet’s prototype inherit from Rectangle. But dashlet instances are now encumbered by a set of irrelevant attributes: opacity, color (and other typical drawing functions like rotate, scale and skew). Think obfuscation. Think memory footprint. Moreover, if inheritance is our thing, there may be more suitable candidates to extend from, such as ContentFrame or Portlet.

Think about it…all we really want to do is see whether two dashlets overlap. Assuming a dashlet has attributes for left, top, width and height (or even if we have to derive them), delegation fulfills the same goal with a much lighter footprint:

Rectangle.prototype.overlaps.call(dashlet1, dashlet2);

 
We can even compare two object literals in this way. Here’s the entire script so you can test it:

var Rectangle = function(left, top, length, width, options) {
	//whatever...
}

Rectangle.prototype.overlaps = function(another) {
	var r1x1 = this.left,
	    r1x2 = this.left + this.width,
	    r1y1 = this.top,
	    r1y2 = this.top + this.height,
	    r2x1 = another.left,
	    r2x2 = another.left + another.width,
	    r2y1 = another.top,
	    r2y2 = another.top + another.height;	    

    return (r1x2 >= r2x1) && (r1y2 >= r2y1) && (r1x1 <= r2x2) && (r1y1 <= r2y2));
}

Rectangle.prototype.overlaps.call(
	{left: 10, top: 10, width 12, height: 6}, 
	{left: 8, top: 15, width 9, height: 16});
//true	
Rectangle.prototype.overlaps.call(
	{left: 10, top: 10, width 12, height: 6}, 
	{left: 8, top: 25, width 9, height: 16});
//false;

 

Generic Functions

This is all great, but wouldn’t it be nice to inject instances into built in functions too? Unfortunately many built in functions are designed to throw a TypeError if the this value is not of the specified type:

Date.prototype.getMilliseconds.apply({year:2010}); 
//TypeError: Date.prototype.getMilliseconds called on incompatible Object

 
Fortunately the EcmaScript 5 specification formalizes the concept of generic functions. These are functions that, by design, allow the this value to be of any type. For example we can invoke String’s search method in the context of an Array.

var hasNumbers = "".search.call(['a','b','c'],/[0-9]/) > -1; 

 
I’ve catalogued the entire list of built-in generic functions at the end of the article. First lets go through some examples by type:

Generic methods of Array.prototype
toString, toLocaleString, concat, join, pop, push, reverse, shift, slice, sort, splice, unshift, indexOf, lastIndexOf, every, some, forEach, map, filter, reduce, reduceRight

Most of these functions will convert this to an Object before invoking, so if we are using a String as the context, those functions that directly manipulate the argument (e.g. push and shift) will surprise the user by returning an Object. However some of Array’s other generic functions work well with Strings:

[].forEach.apply("javascript",[function(char) {console.log("give me a " + char.toUpperCase())}]);
//give me a J
//give me a A
//etc...

var increment = function(char) {return String.fromCharCode(char.charCodeAt(0)+1)};
var hiddenMammal = [].map.call('rhinocerous',increment).join(''); // "sijopdfspvt"

var myObj = {'0':'nil', '1':'one', length:2};
[].push.call(myObj,'two');
myObj; //{'0':'nil', '1':'one', '2':'two' length:3}

 
Generic methods of String.prototype
charAt, charCodeAt, concat, indexOf, lastIndexOf, localeCompare, match, replace, search, splice, split, substring, toLowerCase, toLocaleLowerCase, toUpperCase, to LocaleLowerCase, trim, substr

Most of these functions will convert the this object to a String before invoking. Thus if we are injecting an Array as context we will need to convert the result back to an Array at the end using split.

"".trim.apply([" a","b "]).split(","); 
//["a","b"]

"".toLowerCase.apply(["DIV","H1","SPAN"]).split(","); 
//["div","h1","span"]

"".match.call(["a16","b44","b bar"],/[a-z][0-9]+/g);
//["a16", "b44"]

"".replace.call(
	['argentina','brazil','chile'], 
	/\b./g, function(a){ return a.toUpperCase(); }
).split(',');
//['Argentina',"Brazil","Chile"]

 
Generic methods of Date.prototype
toJSON

This method requires the this value to have a toISOString method.

Object.prototype.toString
OK not strictly a generic function (since every first-class object is an Object – a type error can never be thrown on call or apply – unless using ES 5 strict mode), nevertheless this is a great candidate for demonstrating the power of delegation.

Since the early days of JavaScript, developers have struggled over the best way to determine if an object is an Array. The water-tight solution has only recently seen mainstream adoption and it leverages the ability of an Array to get inside Object’s toString method:

function isArray(obj) {
    return Object.prototype.toString.call(obj) == "[object Array]"; 
}

 
Meta Delegation (sort of)
As of ES 5 the apply function itself has been “generecized”. The second argument need no longer be an array. Any object which has a length and index properties can be used (for example arguments or presumably a string).

ES 5, 15.3.4.3: In Edition 3, a TypeError is thrown if the second argument passed to Function.prototype.apply is neither an array object nor an arguments object. In Edition 5, the second argument may be any kind of generic array-like object that has a valid length property.

 
Sadly browsers have not been quick to adopt this one.

Delegation via “Static” Functions (Mozilla only)
Dmitry Soshnikov points out that the SpiderMonkey engine supports a very simple form of delegation by simply passing arguments to the standalone function definition. Nice!

Array.map('abc', String.toUpperCase); //["A", "B", "C"]
String.toUpperCase(['a']); //"A"

 

Wrap Up

Implementation inheritance is a nice concept – I lived and breathed it for the 12 years I programmed in Smalltalk and Java – but we should be open to leaner, more versatile alternatives where they exist. Function delegation using call and apply allows JavaScript utilities to cherry-pick necessary functionality without the baggage of an unintuitive, bloated and overly complex hierarchy.

Appendix: Generic Function Reference

(See ECMA-262 5th Edition)
15.4.4.2 Array.prototype.toString ( )
15.4.4.3 Array.prototype.toLocaleString ( )
15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , … ] ] ] )
15.4.4.5 Array.prototype.join (separator)
15.4.4.6 Array.prototype.pop ( )
15.4.4.7 Array.prototype.push ( [ item1 [ , item2 [ , … ] ] ] )
15.4.4.8 Array.prototype.reverse ( )
15.4.4.9 Array.prototype.shift ( )
15.4.4.10 Array.prototype.slice (start, end)
15.4.4.11 Array.prototype.sort (comparefn)
15.4.4.12 Array.prototype.splice (start, deleteCount [ , item1 [ , item2 [ , … ] ] ] )
15.4.4.13 Array.prototype.unshift ( [ item1 [ , item2 [ , … ] ] ] )
15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
15.4.4.15 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
15.4.4.16 Array.prototype.every ( callbackfn [ , thisArg ] )
15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] )
15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] )
15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] )
15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] )
15.4.4.22 Array.prototype.reduceRight ( callbackfn [ , initialValue ] )
15.5.4.4 String.prototype.charAt (pos)
15.5.4.5 String.prototype.charCodeAt (pos)
15.5.4.6 String.prototype.concat ( [ string1 [ , string2 [ , … ] ] ] )
15.5.4.7 String.prototype.indexOf (searchString, position)
15.5.4.8 String.prototype.lastIndexOf (searchString, position)
15.5.4.9 String.prototype.localeCompare (that)
15.5.4.10 String.prototype.match (regexp)
15.5.4.11 String.prototype.replace (searchValue, replaceValue)
15.5.4.12 String.prototype.search (regexp)
15.5.4.13 String.prototype.slice (start, end)
15.5.4.14 String.prototype.split (separator, limit)
15.5.4.15 String.prototype.substring (start, end)
15.5.4.16 String.prototype.toLowerCase ( )
15.5.4.17 String.prototype.toLocaleLowerCase ( )
15.5.4.18 String.prototype.toUpperCase ( )
15.5.4.19 String.prototype.toLocaleUpperCase ( )
15.5.4.20 String.prototype.trim ( )
15.9.5.44 Date.prototype.toJSON ( key )
B.2.3 String.prototype.substr (start, length)

Further Reading

Allen Holub in JavaWorldWhy Extends is Evil
Bill Venners: A Conversation with Java’s Creator, James Gosling
Nick Fitzgerald: OOP The Good Parts: Message Passing, Duck Typing, Object Composition, and not Inheritance – An excellent post in which Nick dumps on inheritance some more and outlines three additional alternatives.

43 thoughts on “Delegation vs Inheritance in JavaScript

  1. Note that Gosling said “It’s not so much that class inheritance is particularly bad. It just has problems.”

  2. Good write up, Angus.

    You may also note that the delegation is embedded in the core of ECMAScript, since exactly via auto-delegation the prototype chain is implemented. Once an inherited method is found, it’s applied (in call) in the needed context of this.

    P.S. notice also, that SpiderMonkey for years supports alternative passing a generic object — via a simple argument of a “static” function with the same name as placed on the prototype. E.g.:

    Array.map("abc", function(c) c.toUpperCase()) // ["A", "B", "C"]

    This reflects how Python manages delegation in invocations of its methods. There:

    a.foo()

    is just a syntactic sugar for:

    A.foo(a)

    where A class of a object. The same with Array.prototype.map (which is available directly for instances) and Array.map for more convenient generic application in JS.

    Unfortunately, not standardize yet.

    Dmitry.

  3. I would argue that inheritance isn’t there just for code reuse. Rather, it is mostly used for packaging, and for encapsulating behavior.
    It is true that inheritance is misused on many occasions, but in the end, it has the potential of creating simpler, easier to maintain and easier to read code (while also doing the exact opposite when misused).

    The above pattern has a lot of dangers that come with it, as well as performance hits.
    Having a function declare and manipulate ‘this’ can easily create a lot of mess (for example, when invoking it as is, which will apply the actions to the global object).

    1. Hi Arieh, that was the point I was tying to get across. Use inheritance if want to represent natural hierarchies (ant extends insect) but don’t force an imperfect hierarchy for the sake of reuse. I’d argue the second case is more prevalent

      Regarding risks with this injection…it’s a skill that can be fairly easily learned once the concept is understood

  4. Angus, I agree with your point in general (delegation v. inheritance), but I don’t really like these examples. Reusing functions in this way depends entirely on implementation details of all the objects in question.

    For instance, in the Rectangle/Dashlet example, we’re only able to reuse Rectangle.prototype.overlaps because Rectangle and Dashlet both store their locations in terms of left, top, width, and height. But this requires me to know the innards of the overlaps function. Suppose it changes to depend on some property Rectangle and Dashlet do not share. Now the Dashlet code will break without any indication why.

    I think a better design would be for Dashlet to store it’s location internally as a Rectangle. Something like this:


    var Dashlet = function (left, top, width, height) {
    this.location = new Rectangle(left, top, width, height);
    };

    Dashlet.prototype.overlaps = function (another) {
    return this.location.overlaps(another.location);
    };

    This way we only need to change our code if the public interface to Rectangle changes, which seems reasonable to me.

    I’ll be honest and admit that I don’t know much about ES5’s generic function concept, but it seems to me that many of the examples you provide might have the same problems. For example, I suspect that using Array functions in the context of Strings depends on the fact that both are indexable, have a length property, etc. But the point is that my suspicions might be wrong; I don’t really know how the function works. This leaves my code vulnerable to changes outside my control.

    Anyway, sorry for the lengthy response; I didn’t mean to drone on. Am I wrong? Maybe my fears are unfounded. Let me know if you disagree.

    Thanks.

    1. Sean – I see your point.

      However bear in mind that even if Dashlet does not define its dimensions in the same terms as Recatangle we can derive the correct values and pass them directly as arguments (as you might do with any JavaScript utility)

      For example lets suppose Dashlet stores its dimensions in terms of x1, x2, y1, y2:

      Rectangle.overlaps(
          {left: dashlet1.x1, top: dashlet1.y1, width: dashlet1.x2 - dashlet1.x1, top: dashlet1.y2 - dashlet1.y1},
          {left: dashlet2.x1, top: dashlet2.y1, width: dashlet2.x2 - dashlet2.x1, top: dashlet2.y2 - dashlet2.y1}
      )
      

      Having said that, I like the basis of your suggestion – we could take it a little further and consider Rectangle as a very basic Delegate (much like the Math object) object which simply stores dimensions and has dimension based utilities such as overlap. Then both DrawableRectangle and Dashlet could delegate to it for overlap. (obviously an alternative is to have these objects inherit from Rectangle)

      As for ES 5 generics – I think the idea is that any object whose attribute types match the core interface should be able to take advantage of the function. By the way String is very unlikely to ever lose its length and index attributes.

      Nice comment – thanks!

  5. Nice article. But as you are talking about delegation, why aren’t you also giving an example of borrowing functions? In your dashlet-example I’d actually prefer simply borrowing the function instead of using “call” or “apply”:

    Dashlet.prototype.overlaps = Rectangle.prototype.overlaps;
    myDashlet.overlaps(myOtherDashlet);

    Borrowing is one my favourite features in JS. It gives you the possibility to construct your object using different components (kind of comparable to multiple inheritance).

    // most simple borrow-function
    function borrow(to, from)
    {
    for(var key in from)
    to[key] = from[key];
    }

    // consider OverlapSuite a collection of overlap-test-functions
    // consider ManipulationSuite a collection of functions for
    // rotating rectangular-like objects, etc.
    borrow(Rectangle.prototype, OverlapSuite);
    borrow(Rectangle.prototype, ManipulationSuite);
    borrow(Dashlet.prototype, OverlapSuite);

    Cheers.

  6. Unfortunately I have to disagree with your post, the very premise that inheritance is not good for code reuse is bad. The fact is that the examples you give, and examples of inheritance in general in recent literature are piss poor. One would not have Dashlet inherit from Rectangle so as to get access to the overlaps method. As you say, Dashlet is not a drawable shape. Instead one would refactor common methods out, perhaps into class Rectangular. Both Rectangle and Dashlet could now be subclasses of that without gaining methods and properties that are not required.

    Both classes would find it useful to inherit from other classes too. For example, a Rectangle might be a Shape and a Dashlet might be a Widget. The modern approach is to avoid multiple inheritence, so instead we might use the Module approach, which is, let’s be honest, essentially the same thing. So Rectangle and Dashlet may both rather include the Retangular module thus gaining the overlaps method while inheriting from different classes. The Module pattern is terribly easy to implement in JavaScript (as is classical inheritance, for that matter).

    1. Marc – yep I mentioned the possibility of having everything extend a basic Rectangle in the comments section. But really what is the point? What have we achieved apart from now forcing every Dashlet to be forever a rectangle (and the more we inherit from Rectangle the tighter the coupling becomes) All you gain is reuse and delegation is a more nimble, elegant and agile way to do that.

      By the way the examples may be ‘piss poor’ but they exactly reflect the type of real life inheritance patterns I see all the time – which is why I included them 😉

      1. Sorry, that came across harsher than intended. The point I was trying to make is that the examples appear contrived to show that inheritance is bad. Inheritance is not bad, bad class hierarchies are bad.

        I’m not saying function delegation is bad, it has many uses, just that inheritance is great for code reuse. I may very well want to have Dashlets have Rectangular behavior, and I’d rather inherit that (or include it) than having to call Rectangle.prototype.overlaps.call(dashlet1, dashlet2);.

        I do see that several other comments mention this, and that you’re largely in agreement anyway. I had the page open all day yesterday before posting — that’ll teach me to not refresh 😉

      1. Hi Nick – yeah call is probably more readable when there is only one param being passed. Performance-wise I doubt there is significant difference unless you plan to invoke the function 1000s of times per session

  7. interesting. although i understand the examples of generic functions near the end are contrived for purposes of being obvious…it just strikes me that this technique is only useful for golfing code. i can’t figure out if the ecma standard is envious of ruby or haskell (or both or neither)…but the clumsy use of “identities” for the various type classes (0,[],””) to coerce an evaluation context seems broken. i’m given to conclude that stroustrup’s advice is once again relevant:”avoid esoteric language features”

    1. Ok to me this sounds like ES5 is encouraging browsers to make their built in functions play nice with one of JavaScript’s sweetest features – but maybe I’m biased 😉

  8. Another very good point for inheritance is that it states dependencies “on construction” verses doing it inline:
    Using the fact that closures let us access other scopes to break encapsulation means we create inline dependencies on the global scope. For Natives this is acceptable, but when we start writing dependencies anywhere in our code it can break very fast.

    Thus, one of the important benefits of “classical” inheritance is stating the dependency “on construction” – and in one expected place, in an expected pattern.

    As I said before, inheritance, IMO, is all about order, not code reuse.

    1. Arieh – I agree with you – inheritance should not be about code reuse (that was supposed to be the major point of my article 😉 ) and I also agree that inheritance can represent order very effectively…but only if you have absolute confidence in the hierarchy you are describing – and know that it will not be subject to structural change later on

      e.g. this one is tried and tested

      animal
          insect
              ant
              bee
      

      But often its not that cut and dried – once upon a time we might have done this:

      device
          dial-up
              phone
          wireless
              tv
              radio
      

      then a few years later…whoops…

      device
          dial-up
              phone
              fax
              internet
          wireless
              tv
              radio
          cable
              tv
      

      and a few years after that it got really messy

      device
          dial-up
              phone
              internet
              fax
          wireless
              tv
              radio
              phone
              internet
          cable
              tv
              internet
      

      Admittedly these changes might have evolved over a longer life span than the average program but you get the idea. Hierarchies do evolve – and when we have code wired into them that can be a huge headache.

      Why not organize your code functionally and use delegation which is lightweight and easily maintained? Its a bit like relatives vs. friends. You choose your delegates but you’re stuck with your inheritance chain.

      I have no problem with creating a standalone basic Rectangle object – but instead of having objects inherit from it (which locks in nasty dependencies over time) just delegate to the Rectangle on and adhoc basis. There is still a degree of order :- All rectangle utilities belong under the named object Rectangle and have to be accessed via this object. Moreover if you create Rectangle using the module pattern (but without immediate invocation) you can lock in private variables too.

      Anyway these are great discussions – and this is just my (biased) opinion 😉

      1. As I said – my biggest concern is about inline dependencies. It’s all about the way we maintain our code.
        This isn’t just about TDD (which of course suffers greatly from inline dependencies), but also it creates great problems when we go and package our code.

        Now – delegation is a great tool. So is burrowing – which I prefer, mostly because it usually states the dependencies on object construction. We also both agree that it’s all about using the right tools for the right problems.

        The above patterns might be great tools, but instead of saying – “here’s a tool I seldom see” – you say – “drop inheritance, use delegation”, although I believe your point was to say that we should also remember that not every problem is a nail.

        But what really troubles me is the lack of best practices. Lately we’ve seen a new renaissance of JS patterns. This is a good thing. It reminds us to keep an open mind and that JS truly is a great, dynamic language. But what I really want is that these patterns will come with a disscussion of “where is this good?” “how can I missuse this pattern?” “when should I choose another?”.

        So I’m debating (also I debate because I love to debate (; ), so that when a year from now, when someone looking for new reasources to learn from, he will also find a whole new list of other angles to look for.

        BTW – When I teach OOP, I never give real world examples of OOP abstraction (animal, cat etc). Instead, I teach of building a fractal tree. Or I would point people to Mootool’s Fx familly (now there’s a JS OOP done right!). Or I would even point to the DOM. The point is, when building JS apps, we seldom program animals, but we often write widgets. And widget offer a very large range of interface abstractions that highly benefit from a good (small leveled) hierarchy.

      2. Arieh – it’s true I could have been a bit nicer to inheritance. One problem I need to resolve with my blogs is I’m assuming an advanced audience. For example when I write I imagine an audience that has drunk the OOP kool-aid (as I have too) and therefore I don’t need to dwell on the good things about inheritance. I’m trying to talk up an underused pattern (delegation) which is highly suited to JavaScript – space in a blog is not infinite so I focus on promoting the ‘new’ thing not defending the old. Sometimes you have to overstate the case a little in order to affect old habits – i.e. play devil’s advocate

        Having said all that I do briefly cover the best practice guidelines when I state that inheritance works best when there is a natural extends relationship in real life (I use examples from nature not because they are applicable to real life development but because the inheritance branch of OOP was in itself inspired by classification of the natural world – I am (perhaps badly!) making the point that once we stray from such well defined hierarchies and try to contrive our own, it is easy to get it wrong – to try to impose relationships that don’t exist. Why do I know this – because I repeatedly made bad hierarchies of my own over the course of 12 years 🙂

        Widget sets can form good hierarchies if done well. But I’ve also seen plenty of folks get into trouble by creating new extensions everytime a slightly more complex version of the same widget comes along (e.g Tree -> Draggable Tree -> Draggable Tree with Icons) Yes now it looks like an obvious mistake but when a hierarchy is built iteratively it is easy to get forced into such relationships unless all permutations are carefully assessed before writing code. Thus hierarchies do not always lend themselves to agile development nor are they future-proof (as my ‘device’ hierarchy shows)

        I don’t really intend to sell this best practice over another one. I believe in making the widest range of options available and having the developer make an informed choice (this is why I find crockford difficult at time – even though he is a genius and a terrific writer – he has a habit of telling us to avoid a lot of thing without explaining why – sure his point is to protect naive developers but we don’t become better developers by running away from half the syntax without knowing why – we need to understand the bad parts – and make our own decisions on when and why to avoid them – only then do we and the language grow) So by writing an article on delegation I hope to encourage developers to consider an alternate vocabulary to inheritance – but it is never my intention to say ‘you should do this’ or ‘you should avoid this’ – I leave that up to the developer

        Finally, I really am not anti-inheritance but I want to point out it is more suited (IMO 🙂 ) to class based languages like java and c++). In JavaScript relationships are never static so you can arrange the most perfect prototype-based hierarchy but there is nothing to stop it being modified (corrupted, tweaked) at runtime, and any given line of code can not make assumptions as to the state of the hierarchy at the time of it’s execution. Moreover, JavaScript does not have a clean separation of class from object so the hierarchy tends to get obfuscated quickly

        I apologize for the rambling disorganized comment – it was written from my phone at 5.30 am and I have not been able to review before sending. Nevertheless I was eager to continue this good discussion

  9. Pingback: Quora
  10. Pingback: Quora
  11. I have trying to get the Rectangle.prototype.overlap example to work, no joy!
    In Chrome I get an error “unexpected number”. (Nitpick: There is an extra right paren in the line that calculates if there is overlap – in Rectangle.prototype.overlap in the combined code section.)

Leave a comment