about
Bits Objects JavaScript
02/08/2024
0
Bits: JavaScript Objects
library and user-defined classes and objects
Synopsis:
This page demonstrates uses of JavaScript User-Defined types and their objects. The purpose is to quickly acquire some familiarity with user-defined types and their implementations.- JavaScript defines one special class method constructor().
- The compiler will generate an empty constructor method if the class does not.
- Also, this is the first set of examples to partition code into several files. That supports readability, may improve translation times, and makes maintenance significantly easier.
Demo Notes
1.0 Source Code
1.1 Point user-defined type
/*----------------------------------------------
using JavaScript class
*/
const nlp = "<br />";
const tabp = " "
class Point4D {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.t = new Date();
}
show(name) {
document.write(name, ": Point4D {", nlp, tabp);
document.write(this.x, ", ", this.y, ", ", this.z, nlp, tabp);
document.write(this.t);
document.write(nlp, "}", nlp);
}
update_time() {
this.t = new Date();
}
}
Concept:
JavaScript class syntax:
1.2 Source Code Structure
<!DOCTYPE html>
<html>
<!--
Js_Objects.html
Illustrate creation and use of JavaScript objects.
JavaScript Types.
Number, Bigint, Boolean, String,
Undefined, Null, Symbol, Object
- arrays are typed as objects
Other important library types:
- Date, Maps, Sets, JSON,
All of these are reference types.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
-->
<head>
<script src="Analysis.js"></script>
<script src="Point.js"></script>
<script>
/*----------------------------------------------
display text heading
*/
function heading() {
/*-- code elided --*/
}
/*----------------------------------------------
built in objects
*/
function demo_builtin() {
/*-- code elided --*/
}
/*----------------------------------------------
crafting object by hand
*/
function demo_Object() {
/*-- code elided --*/
}
/*----------------------------------------------
using JavaScript class
*/
function demo_Point4D() {
/*-- code elided --*/
}
/*----------------------------------------------
exploring concequences of JS object model
*/
function demo_reftype() {
/*-- code elided --*/
}
/*------------------------------------------------
Demonstration starts here
*/
function execute() {
showNote("Demo Objects")
demo_builtin();
demo_Object();
demo_Point4D();
demo_reftype();
print(nl + "That's all Folks!" + nl);
}
</script>
<style>
body {
font-family:'Comic Sans MS', Tahoma;
padding:2em;
}
</style>
</head>
<body>
<div id="objects"></div>
<script>
heading();
execute();
</script>
</body>
</html>
Page structure:
Dependencies:
Execution:
1.3 Built-in Types
function demo_builtin() {
showNote("Built-in instances", 25);
let d = 3.1415927;
showType(d, "d");
println("---");
let s = "s";
showType(s, "string");
println("---");
let a = [1, 2, 3];
showType(a, "array");
println("---");
let o = new Object();
o.elem = "some element";
o.say = function() { document.write("Hello" + nl)};
showType(o, "o");
o.say();
showOp("more elaborate data");
let arr = [1, 'z', [1, 2, 3], true];
showType(arr, "arr");
println("---");
/* add show method to existing array */
println(
"you can add new elements to any object, including" + nl +
"scalar data, composite data like arrays and functions."
)
arr.show = function(nm) {
document.write(nm, " [ ");
arr.forEach(element => {
document.write(element, " ");
});
document.write("]" + nl);
}
showOp("arr.show(nm)");
arr.show("arr");
println(nil);
println(
"Here see the results of using two other analyzer methods" +nl +
"on the arr array:"
)
/*------------------------------------------------------------------
showTypeShowable uses show(...) method provided by analyzed type.
It works with any object that provides a show(...) method.
*/
/* so now showTypeShowable can be used */
showOp("showTypeShowable(arr, \"arr\")");
showTypeShowable(arr, "arr");
showOp("showObject(arr, \"arr\")");
showObject(arr, "arr");
print(nl);
}
-------------------------
Built-in instances
-------------------------
d: number
size: 8, value: 3.1415927
---
string: string
size: 2, value: s
---
type: object
array: [
1, 2, 3
]
size: 24
---
type: object
o: {
"elem":"some element"
}
size: 24
Hello
--- more elaborate data ---
type: object
arr: [
1, "z", [1,2,3], true
]
size: 38
---
you can add new elements to any object, including
scalar data, composite data like arrays and functions.
--- arr.show(nm) ---
arr [ 1 z 1,2,3 true ]
Here see the results of using two other analyzer methods
on the arr array:
--- showTypeShowable(arr, "arr") ---
arr, object, size: 38
value: arr [ 1 z 1,2,3 true ]
--- showObject(arr, "arr") ---
arr: [
1, "z", [1,2,3], true
]
1.4 User-defined Objects
function demo_Object() {
showNote("User-defined object literal", 35);
const dev = {
name:"Jim",
job:"Retired from Syracuse University",
hobby:"Developing software",
projects: [ 'Bits language comparisons', 'Stories', 'Bites' ]
}
showObject(dev, "dev");
/* creating show function tailored to dev objects */
dev.show = function(nm) {
document.write(nm, ": {",nl,tab,"name: ", this.name,
nl, tab, "job: ", this.job, nl, tab, "hobby: ",
this.hobby, nl, tab, "projects: ", this.projects,
nl, "}<br />");
}
/* using 3 ways to display information about an object */
showOp("dev.show(\"dev\")");
dev.show("dev");
showOp("showTypeShowable(dev, \"dev\")");
showTypeShowable(dev, "dev");
showOp("showType(dev, \"dev\")");
showType(dev, "dev", 4, 1);
}
-----------------------------------
User-defined object literal
-----------------------------------
dev: {
"name":"Jim", "job":"Retired from Syracuse University", "hobby":"Developing software", "projects":["Bits language comparisons","Stories","Bites"]
}
--- dev.show("dev") ---
dev: {
name: Jim
job: Retired from Syracuse University
hobby: Developing software
projects: Bits language comparisons,Stories,Bites
}
--- showTypeShowable(dev, "dev") ---
dev, object, size: 182
value: dev: {
name: Jim
job: Retired from Syracuse University
hobby: Developing software
projects: Bits language comparisons,Stories,Bites
}
--- showType(dev, "dev") ---
type: object
dev: {
"name":"Jim",
"job":"Retired from Syracuse University",
"hobby":"Developing software",
"projects":["Bits language comparisons","Stories","Bites"]
}
size: 182
1.5 Point4D
function demo_Point4D() {
showNote("Using JavaScript class", 30);
let p1 = new Point4D(1, 2, 3);
showOp("showObject(p1, \"p1\")");
showObject(p1, "p1");
showOp("p1.show(\"p1\")");
p1.show("p1");
showOp("showTypeShowable(p1, \"p1\")");
showTypeShowable(p1, "p1");
showOp("showType(p1, \"p1\")");
showType(p1, "p1: Point1");
println(nil);
}
------------------------------
Using JavaScript class
------------------------------
--- showObject(p1, "p1") ---
p1: {
"x":1, "y":2, "z":3, "t":"2024-02-08T16:38:22.965Z"
}
--- p1.show("p1") ---
p1: Point4D {
1, 2, 3
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
--- showTypeShowable(p1, "p1") ---
p1, object, size: 24
value: p1: Point4D {
1, 2, 3
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
--- showType(p1, "p1") ---
type: object
p1: Point1: {
"x":1, "y":2, "z":3, "t":"2024-02-08T16:38:22.965Z"
}
size: 24
1.6 Consequences of Reference Types
function demo_reftype() {
showNote(
"Exploring consequences of JavaScript reference types:", 65
)
let p1 = new Point4D(0, 1, 2);
p1.show("p1");
showOp("let p2 = p1");
let p2 = p1;
p2.show("p2");
isSameObject(p2, "p2", p1, "p1");
showOp("p2.z = -42");
p2.z = -42;
p2.show("p2");
p1.show("p1");
isSameObject(p2, "p2", p1, "p1");
showNote(
"All JavaScript variables are reference types. So assignments assign" + nl +
" " + "references, not values. And so changing target, p2, changed source, p1",
85
)
print(nl);
-----------------------------------------------------------------
Exploring consequences of JavaScript reference types:
-----------------------------------------------------------------
p1: Point4D {
0, 1, 2
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
--- let p2 = p1 ---
p2: Point4D {
0, 1, 2
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
p2 is same object as p1
--- p2.z = -42 ---
p2: Point4D {
0, 1, -42
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
p1: Point4D {
0, 1, -42
Thu Feb 08 2024 10:38:22 GMT-0600 (Central Standard Time)
}
p2 is same object as p1
-------------------------------------------------------------------------------------
All JavaScript variables are reference types. So assignments assign
references, not values. And so changing target, p2, changed source, p1
-------------------------------------------------------------------------------------
2.0 Analysis and Display
/*------------------------------------------------
Display and Analysis functions
*/
const nl = "<br />";
const tab = " "
const nil = "";
function print(str) {
document.write(str);
}
function println(str) {
document.write(str + "<br />");
}
/*------------------------------------------------
Display emphasized text
*/
function showNote(text, n=20) {
let s = '-'.toString().repeat(n);
document.write(s + "<br />");
document.write("<span> </span>", text, "<br />");
document.write(s + "<br />");
}
/*------------------------------------------------
Show an operation expression surrounded with a few dashes
*/
function showOp(text) {
document.write("--- ");
document.write(text)
document.write(" ---<br />");
}
/*--------------------------------------------------------------------
Show basic type information
*/
function showType(t, nm, left=4, width=7) {
if(typeof t != typeof Object()) {
println(nm + ": " + typeof t);
print("size: " + sizeof(t) + ", value: " + t);
}
else {
println("type: " + typeof t);
showObject(t, nm, left, width);
print("size: " + sizeof(t));
}
println(nil);
}
/*--------------------------------------------------------------------
Show type information using object's show() method
*/
function showTypeShowable(t, nm) {
print(nm + ", " + typeof t);
print(", size: ");
println(sizeof(t));
print("value: ");
t.show(nm);
}
/*--------------------------------------------------------------------
Do references o1 and o2 have same address (point to same instance)
*/
function isSameObject(o1, nm1, o2, nm2) {
if (o1 === o2) {
println(nm1 + " is same object as " + nm2)
}
else {
println(nm1 + " is not same object as " + nm2)
}
}
/*--------------------------------------------------------------------
Create a string containing n non-breaking spaces, ....
Part of formatJSONstr(...)
*/
function indent(n) {
let tmp = "";
for(i=0; i<n; ++i) {
tmp += " ";
}
return tmp;
}
/*--------------------------------------------------------------------
Replace comma character with comma escape, e.g., ,.
Expects index to point to comma in str. This is done to
avoid splitting inner array by JSON.stringify.
Part of formatJSONstr(...)
*/
function replaceComma(str, index) {
if(index < 0 || str.length <= index) {
return str;
}
let tmp = str.substr(0, index-1) + "," + str.substr(index);
// document.writeln("test: " + JSON.stringify('1,2'));
return tmp;
}
/*--------------------------------------------------------------------
Treat inner array as a single element for JSON string formatting.
Part of formatJSONstr(...)
*/
function weldArray(jstr) {
isArray = false;
tmp = jstr;
let j=0;
for(i=0; i<jstr.length; ++i) {
j += 1;
switch(jstr[i]) {
case '[':
if(i != 0) { // don't count outer array
isArray = true;
}
break;
case ']':
isArray = false;
break;
case ',':
if(isArray) {
tmp = replaceComma(tmp, j);
j += 4;
}
break;
}
}
return tmp;
}
/*--------------------------------------------------------------------
Format JSON string to indent left spaces and show rows of width elements
*/
function formatJSONstr(jstr, left=4, width=8) {
let indtCache = indent(left);
jstr = weldArray(jstr);
jstr = jstr.trim();
let char1 = jstr[0];
let char2 = jstr[jstr.length - 1];
let jstrm = jstr.substring(1, jstr.length - 1); // remove delimiters
let fstr = jstrm.split(/[,]+/); // regex selects on either " " or ,
let fm = char1 + "<br />" + indtCache;
for(i=0; i<fstr.length; ++i) {
fm += fstr[i] + ", ";
if((i+1) % width === 0 && i != fstr.length -1) {
fm += "<br />" + indtCache;
}
}
fm = fm.substring(0, fm.length - 2);
fm += "<br />" + char2 + "<br />";
return fm;
}
/*--------------------------------------------------------------------
Use JSONstringify to show all data members of object with body
indented by left spaces and elements shown in rows of specified
width. Used in showType(...)
*/
function showObject(obj, nm, left=4, width=7) {
document.write(nm, ": ");
let fmts = formatJSONstr(JSON.stringify(obj), left, width);
document.write(fmts);
}
/*--------------------------------------------------------------------
Iterate through object's own keys, ignore objects, and display
- only shows top level elements, e.g., no recursion
- not used in demo
- here to illustrate iterating through object elements
*/
function showObject_alt(obj, nm) {
let str = "";
for(let [key, value] of Object.entries(obj)) {
if(obj.hasOwnProperty(key) && typeof value != typeof Object) {
str += "{" + key + ": " + value + "}, ";
}
}
/* remove trailing comma and space */
str = str.substring(0, str.length - 2);
document.write(nm, " { ", str, " }", nl);
}
/*--------------------------------------------------------------------
Evaluate object's size by iterating through own properties
// https://gist.github.com/pgpbpadilla/10344038
*/
function sizeof(object) {
var objectList = [],
stack = [ object ],
bytes = 0,
value,
i;
while (stack.length) {
value = stack.pop();
if (typeof value === 'boolean') {
bytes += 4;
} else if (typeof value === 'string') {
bytes += value.length * 2;
} else if (typeof value === 'number') {
bytes += 8;
} else if (typeof value === 'object'
&& objectList.indexOf(value) === -1) {
objectList.push(value);
for (i in value) {
if (value.hasOwnProperty(i)) {
stack.push(value[i]);
}
}
}
}
return bytes;
}
Functions:
Display Functions:
Analysis Functions:
2.0 Build
local machine
C:\github\JimFawcett\Bits\Javascript\Js_Objects
> start firefox C:\github\JimFawcett\Bits\Javascript\Js_Objects\Js_Objects.html
C:\github\JimFawcett\Bits\Javascript\Js_Objects
>
github site
clone Bits repository and double click on Js_Objects.html
2.0 VS Code View
3.0 References
Reference | Description |
---|---|
JavaScript Tutorial - w3schools | Interactive examples |
JavaScript Reference - MDN | Informal syntax reference |