Code: Select all
var intValue = 1;
var floatValue = 3.0;
var stringValue = "This is a string\n";
var sqString = 'This is also a string';
Arrays
Code: Select all
var emptyList = [];
var homogenousList = [1, 2, 3];
var heterogenousList = ["one", 2, 3.0];
Property Maps
Code: Select all
var emptyMap = {};
var homogenousMap = {"one": 1, "two": 2, "three": 3};
var heterogenousMap = {"one": 1,
"two": "two",
"three": 3.0};
Access
Code: Select all
// Dot notation property access
window.alert("Homogenous map property \"one\" "
+ homogenousMap.one);
// Subscript notation property access
window.alert("Homogenous map property \"two\" "
+ homogenousMap["two"]);
Code: Select all
homogenousMap["one"] = 10;
homogenousMap.two = 20;
Code: Select all
delete homogenousMap["one"];
delete homogenousMap.two;
Code: Select all
for (var key in heterogenousMap) {
window.alert("Heterogenous map property \""
+ key
+ "\" = "
+ heterogenousMap[key]);
}
Code: Select all
var callable = function (message) { // <-- notice assignment
window.alert("Callable called with message = "
+ message);
}
function createClosure(initial) {
var res = function () {
initial = initial + 1;
window.alert("Closure with modified state "
+ initial);
}
return res;
}
function callCallable(f, x) {
f(x);
}
function composeCallables(f, g, x) {
f(g(x));
}
Functions are first-class objects. That means that they can be created dynamically, stored, passed and returned just like any other value.
Objects
Code: Select all
function MyObject(name, value) {
this.name = name;
this.value = value;
}
The object constructor, MyObject, is an object constructor not in how it's defined, which looks like any other Javascript function, but in how it's ''invoked''.
Code: Select all
var my = new MyObject("foo", 5);
Object Prototype
Part of what makes a language object oriented is that data not only has properties but also ''behaviors''. Also known as: member functions; methods; and object messages. To implement a member function in Javascript one would be tempted to write something like what's below based on the member initialization exampled above.
Code: Select all
[color=#FF0000]function BadObject(data) {
this.data = data
this.memberFunction = function () {
// ...functions on data...
}
}[/color]
Enter the prototype member.
The internal object member, prototype, has language defined significance in that it is used for resolving property names if the property isn't found in the current property map. It's considered internal because, while the instance's prototype member is ''inherited'' from the ''constructor's'' prototype member, it cannot be accessed directly from the object instance itself. The defined prototype member is a property map itself which holds members for property name resolution. Consider the example below:
Code: Select all
var parentPropertyMap = {"bar": "I'm the bar"};
// Define the constructor with inheritable properties
function ChildObject(foo) {
this.foo = foo;
}
ChildObject.prototype = parentPropertyMap;
childPropertyMap1 = new ChildObject("I'm the foo1");
childPropertyMap2 = new ChildObject("I'm the foo2");
// Prints "childPropertyMap1.foo = I'm the foo1"
window.alert("childPropertyMap1.foo = " + childPropertyMap1.foo);
// Prints "childPropertyMap2.foo = I'm the foo2"
window.alert("childPropertyMap2.foo = " + childPropertyMap2.foo);
// Prints "childPropertyMap1.bar = I'm the bar"
window.alert("childPropertyMap1.bar = " + childPropertyMap1.bar);
// Prints "childPropertyMap2.bar = I'm the bar"
window.alert("childPropertyMap2.bar = " + childPropertyMap2.bar);
Code: Select all
function ChildObject(foo) {
this.foo = foo;
}
Code: Select all
var parentPropertyMap = {"bar": "I'm the bar"};
...
ChildObject.prototype = parentPropertyMap;
Code: Select all
childPropertyMap1 = new ChildObject("I'm the foo1");
childPropertyMap2 = new ChildObject("I'm the foo2");
Therefore, by implementing the prototype member of the constructor function, we can think of the constructor function itself as the "class" object. Complete with static class functions:
Code: Select all
function ClassObject() {}
ClassObject.staticClassFunction = function(x) {
return x * 2;
}
Code: Select all
function ClassObject() {}
ClassObject.staticClassVariable = 5;
Code: Select all
function ClassObject() {}
ClassObject.prototype.sharedMember = 5;
Code: Select all
function ClassObject(x) {
this.x = x;
}
ClassObject.prototype.memberFunction = function(x) {
return x * this.x;
}
Code: Select all
function Message(message) {
this.message = message;
}
Message.prototype.show = function() {
window.alert("Message.show() with message = "
+ this.message);
}
Code: Select all
//////////////////////////////////////
// Basic Types
var intValue = 1;
var floatValue = 3.0;
var stringValue = "This is a string\n";
///////////////////////////////////////
// Array
var emptyList = [];
var homogenousList = [1, 2, 3];
var heterogenousList = ["one", 2, 3.0];
///////////////////////////////////////
// Property Map
//
var emptyMap = {};
var homogenousMap = {"one": 1, "two": 2, "three": 3};
var heterogenousMap = {"one": 1,
"two": "two",
"three": 3.0};
///////////////////////////////////////
// Functions as values
//
var callable = function (message) { // <-- notice assignment
window.alert("Callable called with message = "
+ message);
}
function createClosure(initial) {
var res = function () {
initial = initial + 1;
window.alert("Closure with modified state "
+ initial);
}
return res;
}
///////////////////////////////////////
// Functions as arguments
//
function callCallable(f, x) {
f(x);
}
function composeCallables(f, g, x) {
f(g(x));
}
///////////////////////////////////////
// Objects
//
function MyObject(name, value) {
this.name = name;
this.value = value;
}
///////////////////////////////////////
// Objects with Member Functions
//
function Message(message) {
this.message = message;
}
Message.prototype.show = function() {
window.alert("Message.show() with message = "
+ this.message);
}
///////////////////////////////////////
// Demo Utilities
//
function quote(message) {
return "\"" + message + "\"";
}
///////////////////////////////////////
// HTML Invoked demonstration
//
//
function main() {
window.alert("Integer = " + intValue);
window.alert("Float = " + floatValue);
window.alert("String = " + stringValue);
for (var item in emptyList) {
window.alert("Empty list item = " + item);
}
// Script style index iteration
for (var i in homogenousList) {
window.alert("Homogenous list item = "
+ homogenousList[i]);
}
// C style index iteration
for (var i=0; i < heterogenousList.length; ++i) {
window.alert("Heterogenous list item = "
+ heterogenousList[i]);
}
// Dot notation property access
window.alert("Homogenous map property \"one\" "
+ homogenousMap.one);
// Subscript notation property access
window.alert("Homogenous map property \"two\" "
+ homogenousMap["two"]);
for (var key in heterogenousMap) {
window.alert("Heterogenous map property \""
+ key
+ "\" = "
+ heterogenousMap[key]);
}
callable("(Function value invoked)");
closure();
closure();
callCallable(closure);
composeCallables(callable, quote, "My Message");
var my = new MyObject("foo", 5);
window.alert("MyObject my.name = " + my.name);
window.alert("MyObject my[\"value\"] = " + my["value"]);
var msg = new Message("bar");
for (var key in Message.prototype) {
window.alert("Message prototype member \""
+ key
+ "\" = "
+ Message.prototype[key]);
}
window.alert("Message msg.message = " + msg.message);
msg.show();
}