The demo code runs in your browser. Rather than put the code in this html file twice I assume that you are using a browser that easily shows the html source of the current page, which includes the JavaScript source. The yields of these code fragments are computed by your browser and rendered in this browser window thus: {your yield | my yield}.
In the following “object” is always used in the sense of JavaScript—merely a mutable map from strings to values.
We make a new instance { |[object Object]} g. The lights are all out: {|0}. We turn on lights 3 and 6 then observe: {|72}. We turn off light 6 and then: {|8}.
I have two contractors ON and OFF. I trust ON to turn lights on and OFF to turn them off. They are each a function taking as an argument another function which provides to them the tool they need to do their job. I do ON(g.on) and OFF(g.off) which grants each of them just the authority it needs. If var g = grp(0); ON(g.on); OFF(g.off); g.observe(); yields 4, then I can be sure that ON turned that bit on. This conclusion does not involve examining the code of OFF.
JavaScript veterans will find the expression g.on(4) familiar but it is a different construction than is taught in most JavaScript tutorials where the practice is for on’s code to refer to this to get the instance variables.
Writing g.on(4) delivers the object g to the body of the on function as the value of this.
Our code for on does not need or refer to this.
The conventional JavaScript constructor for grp might look something like Cgrp also in the head of the source of this file.
Note that it is not necessary to nest functions in the conventional style for there is no reference to outer variables from within the nested functions.
This gives similar results: {|72}.
There is a vital difference: The code OFF(Cg.off) fails for a function is delivered to OFF which lacks access to the cell with the 32 bits.
If OFF is coded
function OFF(f){f(1<<3);}
the conventional body of off defined in Cgrp finds that its value of this is null:
{|72};
(72 = 1<<6 | 1<<3)
Bit 3 is still on!
If the interface to OFF were changed to take Cg instead of Cg.off then we would have to look at the code for OFF to be sure that it did not turn on bits.
Perhaps the Pizza superset of Java gains this advantage.
In jargon introduced elsewhere, g.off and g.on are facets of g.
These two styles can be mixed so that instance variables stored in the base object are public, in the sense of Java, while instance variables in the closure are private in the sense of Java.
There is a new language feature in JavaScript which explicitly provides classes more like C++ and Java. I do not know how that abstracts data.
As a post-script I show that two banks of lights can be instantiated. We left bank g with just light 3 on: {|8}. We make a new bank, g2, with lights 0 thru 3 on: {|15}. The first bank is unaffected: {|8}.
Daved Hopwood points out a pit-fall in this and I counter with further observations.