["tilescript", ["html", "

Press to try Javascript examples.\nThe result will be shown to the Transcript.

"], ["html", "

We do the hiding inside of a JavaScript function by putting all the\nobject's machinery into interior variables of the function and then\nreturning a one level more deep environment that uses the interior\nvariables as globals. This device also traces back to Lisp, and is\ncalled a 'closure'. We will make a simple object that can do the Sum\nroutine you did as your first example, and can obers how many messages\nwere sent to it.

\n"], ["source", "makeObs = function() {\n var sum = function(x, y) { return x + y },\n msgCount = 0\n return function(message) {\n msgCount++\n switch (message.name) {\n case 'add' : return sum(message.x, message.y)\n case 'stats': return alert('message count = ' + msgCount)\n default : throw 'message not understood: ' + message.name }}} "], ["html", "

We can make an object called 'ob' by saying:

"], ["source", "ob = makeObs()"], ["html", "

We can invoke a completely internal method by sending a message to the object:

"], ["source", "ob({name: \"add\", x: 35, y: 7})"], ["html", "

Let's see what is going on here. When we made the object, lines\n5-10 are made into a function with an environment of 'sum' and\n'msgCount', and this group is put into the variable 'ob'. So a\npicture of 'ob' would look something like:

"], ["html", "

So 'ob' is the name part of a dictionary entry, and its meaning\nis the function in blue. This function has a private environment made\nup its parameters (just one called message ) and a dictionary of the\ntwo variables which hold the summation function and a holder for\ncounting the number of message sends.

\n"], ["html", "

(SEE MY E-MAIL FOR A COMMENT ON THE DIAGRAM AND PARAGRAPH ABOVE.)

\n

In the invocation of 'ob',

\n"], ["source", "ob({name: \"add\", x: 35, y: 7})"], ["html", "

the first thing that happens is that the message count (msgCount)\ngets increased by 1. It started with 0 so now it is 1. The next thing\nthat happens is that the parameter that got put into message

\n"], ["source", "{name: \"add\", x: 35, y: 7}"], ["html", "

has its first part extracted by message.name . This value is 'add' \nand so the case labeled 'add' is chosen and executed. This finds and\nexecutes the 'sum' function using parameters found in other parts of\nthe message. The value of this is '42' and this is returned to the\noriginal invoker.

\n\n

Notice that the interior of this object is completely protected\nfrom the outside world. We can protect it further by requiring that\nevery message contain the identity of the sender so that there can be\na check for each case to see if that sender should be allowed to ask\nfor that function to be invoked. This would make these real objects\nhave about the protection that entire machines have on the\ninternet. No one can tell them what to do, only requests can be\nmade. Quite a few of the issues here are architectural and we will\ndiscuss them further in the Architectural Issues section ahead.

\n\n

For now, let's just note that this had to be done in a contrived\nway in JavaScript -- it is really not set up for real objects. But\nalso we should praise JavaScript for having the mechanisms to allow\nthis to be done at all.

\n\n

As programmers, we certainly don't want to have to think this\nthrough every time, nor do we want to have to write all the machinery\nto do this. We really want to add a feature to our language that makes\nwhat we have to write as clean as possible, and we will see how to do\nthat ahead.

\n"] ]