Programming on a Jerker PART 6: JavaScript Prototype Gotchas or: How we don’t need no stinkin’ prototypes

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

Prototypal JavaScript has two “gotchas” that make complete sense, once you understand what is going on with them. Prototypal sharing of properties can sometimes lead to unexpected results. For instance the variables:
hidden_type.prototype.my_duplicate_var
and
visible_type.my_duplicate_var
these refer to the same value as you can see below.

console.clear();
var hidden_type = function () {};
hidden_type.prototype.my_duplicate_var = 42;
var visible_type = function () {};
visible_type.prototype = Object.create(hidden_type.prototype);
visible_type.prototype.constructor = visible_type;

var visible_obj = new visible_type();
console.log(visible_obj);
hidden_type.prototype.my_duplicate_var = 1066;
console.log(visible_obj);

console.log(hidden_type.prototype.my_duplicate_var);
console.log(visible_obj.my_duplicate_var);

The console output of the above code.

Object { my_duplicate_var=42, constructor=function()}
Object { my_duplicate_var=1066, constructor=function()}
1066
1066

The change from 42 to 1066 can be surprising, but logical, when programming prototypal JavaScript. This cannot happen with classless JavaScript because the objects do not share in a prototypal manner, they are rude.

Here we see what happens when there is more than one property of the same name in prototypal JavaScript. There are two variables called “my_duplicate_var” one is the hidden_type, and one is the visible_type. When the “visible_type.my_duplicate_var” gets deleted it actually doesn’t because JavaScript examines visible_type’s prototype chain and finds the other duplicate: “my_duplicate_var”. There is no prototype chain to refer to in classless JavaScript.

console.clear();
var hidden_type = function () {};
hidden_type.prototype.my_duplicate_var = 42;
var visible_type = function () {};
visible_type.prototype = Object.create(hidden_type.prototype);
visible_type.prototype.constructor = visible_type;

var visible_obj = new visible_type();
visible_obj.my_duplicate_var =8675309;
visible_obj.my_singular_var =Math.PI;

console.log(visible_obj);
delete visible_obj.my_duplicate_var;
delete visible_obj.my_singular_var;
console.log(visible_obj);

The console output of the above code.

Object { my_duplicate_var=8675309, my_singular_var=3.141592653589793, 
 constructor=function()}
Object { my_duplicate_var=42, constructor=function()}

Part  1  2  3  4  5  6  7

Programming on a Jerker PART 5: Classless Versus Prototype Speed Test or: How I learned that benchtesting javascript is difficult

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

Well colour me surprised; sorry about the exceptional Canadian spelling. I expected to see negligible execution time differences when comparing similar classless and prototypal JavaScript programs with each other. Both test programs have a child function call a parent function 10,000,000 times. I ran the classless and the prototypal in Chrome and Firefox ten times each in the console. Yes, unscientific, but good enough for me. The numbers below are in milliseconds.

26840 31984 31291 30123 31636 30487 38455 37558 40240 38358
Chrome Functional average: 33697
22399 23928 26580 22713 23162 20189 26737 25834 20698 20698 
Firefox Functional average: 23294
27807 28048 27414 27326 27693 31926 29182 39366 33540 34279
Chrome Prototypal average: 30658
30936 29869 28678 28187 30045 38294 32238 26926 25878 26271
Firefox Prototypal average: 29732

As you can see, Firefox was faster in both cases. The surprising fact is that the classless type was faster in Firefox, slower in Chrome. But overall, there wasn’t  much difference, especially when you consider, there were 20,000,000 function calls. I consider prototypal and classless JavaScript to have about the same speeds.

I hear you say: “But all that copying has to use more memory in the classless version, Steen.”

To this, I say to you: “yep you are right. But this is because Crockford’s classless style require objects have their own copy of duplicate code in many instances, more memory is used.”

It bears repeating, “my cheap android phone has 12gb”,  memory just does not matter anymore.

Here is the classless “Functional” program:

clear();
function privitizeNewVariables(specs) {
    if (!specs.is_private) {
        var members = Object.assign({}, specs);
        members.is_private = true;
        return members;
    }
    return specs;
}
function newFunctionalLevel1(specs) {
    var members = privitizeNewVariables(specs);
    functionalWasteTime = function (i) {
  //      console.log('in functionalLevel1', i)
        return i;
    };
    return Object.freeze({
        functionalWasteTime: functionalWasteTime
    });
}
function newFunctionalLevel2(specs) {
    var members = privitizeNewVariables(specs);
    var an_animal = newFunctionalLevel1(members);
    functionalWasteTime = function (i) {
    //    console.log('in functionalLevel2', i)
        return an_animal.functionalWasteTime(i);
    };
    return Object.freeze({
        functionalWasteTime: functionalWasteTime
    });
}
var functional_obj = newFunctionalLevel2({});
var loops =10000000;
var start = +new Date();
var functional_accum = 0;
for (var j = loops; j > 0; j--) {
  functional_accum += functional_obj.functionalWasteTime(j);
}
var end = +new Date();
var diff = end - start;
console.log('functional', diff);

Here is the this and new using “Prototypal” program, I must say it is a lot shorter:

clear();
var prototypeLevel1 = function () {};
prototypeLevel1.prototype.functionalWasteTime = function (i) {
   // console.log('in prototypeLevel1', i)
    return i;};
var prototypeLevel2 = function () { };
prototypeLevel2.prototype = Object.create(prototypeLevel1.prototype);
prototypeLevel2.prototype.constructor = prototypeLevel2;
prototypeLevel2.prototype.functionalWasteTime = function (i) {
    //console.log('in prototypeLevel2', i)
    prototypeLevel1.prototype.functionalWasteTime(i);};
var prototype_obj = new prototypeLevel2();

var loops =10000000;
var start = +new Date();
var functional_accum = 0;
for (var j = loops; j > 0; j--) {
    functional_accum += prototype_obj.functionalWasteTime(j);
}
var end = +new Date();
var diff = end - start;
console.log('prototypal', diff);

Part  1  2  3  4  5  6  7

Programming on a Jerker PART 4: Laughing at the Deadly Diamond Problem or: How I learned to love mulitple inheritence

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

Inheritance with classes is difficult because you have two programming entities that must be kept in sync; your program and the program’s class taxonomy. Any changes to the class taxonomy will cascade into the program, and vice versa. With classless JavaScript there is no taxonomy, thus there is only one thing to change, the program. And, the program will always be consistent within itself.

A graphical representation of the objects in the program below could be:

Animal
  Snake
  Bird
    Duck
  Mammal
    Platypus

But this would not capture the fact that the Platypus is closely programmatically related to both the Snake and Duck. The platypus inherits its egg laying ability from the Snake, and its bill from the Duck.

The example program below shows how to easily accomplish multiple [inheritance] in non-prototype based JavaScript OOP. Code superfluous to the example has been stripped away.

console.clear();
function privitizeNewVariables(specs) {
  if (!specs.is_private) {
    var members = Object.assign({}, specs);
    members.is_private = true;
    return members;
  }
  return specs;
}
function newAnimal(specs) {
  var members = privitizeNewVariables(specs);
  var bodyDescription = function () {
    var body_description = members.common_name + ' : ';
    if (members.color_scheme) {
      body_description += members.color_scheme + ',';
    }
    if (members.body_covering) {
      body_description += members.body_covering + ',';
    }
    if (members.eat_with) {
      body_description += members.eat_with + ',';
    }
    return body_description;
  };
  return Object.freeze({
    bodyDescription: bodyDescription
  });
}
function newSnake(specs){
  var members = privitizeNewVariables(specs);
  members.makeOffspring = function () {
    console.log('Offspring by: laying eggs')
  }
  var an_animal = newAnimal(members);
  return Object.freeze({
    makeOffspring: members.makeOffspring
  });
}
function newBird(spec) {
  var members = privitizeNewVariables(spec);
  var an_animal = newAnimal(members);
  return Object.freeze({
  });
}
function newDuck(spec) {
  var members = privitizeNewVariables(spec);
  members.eat_with ='bill';
  var an_animal = newBird(members);
  return Object.freeze({
    eat_with: members.eat_with,
  });
}
function newMammal(spec) {
  var members = privitizeNewVariables(spec);
  if (!members.hasOwnProperty('body_covering')) {
    members.body_covering ='fur';
  }
  if (!members.hasOwnProperty('eat_with')) {
    members.eat_with ='teeth';
  }
  if (!members.hasOwnProperty('makeOffspring')) {
    members.makeOffspring = function () {
      console.log('Offspring by: gestating baby');
    }
  }
  var an_animal = newAnimal(members);
  return Object.freeze({
    bodyDescription: an_animal.bodyDescription,
    movesBy: members.movesBy,
    makeOffspring: members.makeOffspring,
  });
}
var egg_laying_snake = newSnake({common_name: 'borrowing egg laying'});
var duck_with_bill = newDuck({common_name: 'borrowing duck bill'});
var platypus_spec = {common_name: 'Platty the platypus',
    color_scheme : 'dark brown',
    eat_with: duck_with_bill.eat_with,
    movesBy: function (){ console.log('Moves by: swimming');},
    makeOffspring: egg_laying_snake.makeOffspring};
var a_platypus = newMammal(platypus_spec);

console.log(a_platypus.bodyDescription());
a_platypus.movesBy();
a_platypus.makeOffspring();

Here is the console output for the above:

Platty the platypus : dark brown,fur,bill,
Moves by: swimming
Offspring by: laying eggs

Explanation:

var egg_laying_snake = newSnake({common_name: 'borrowing egg laying'});
var duck_with_bill = newDuck({common_name: 'borrowing duck bill'});
var platypus_spec = {common_name: 'Platty the platypus',
    color_scheme : 'dark brown',
    eat_with: duck_with_bill.eat_with,
    movesBy: function (){ console.log('Moves by: swimming');},
    makeOffspring: egg_laying_snake.makeOffspring};
var a_platypus = newMammal(platypus_spec);

We create a Snake and a Duck object to borrow properties from. The platypus object takes the egg laying function of a Snake, and the value ‘bill’ for its ‘eat_with’ property and overrides the default Mammal properties. The platypus gets its ‘fur’ from being a mammal. Yep, it’s that simple.

Part  1  2  3  4  5  6  7

Programming on a Jerker PART 3: Non-Prototype Based JavaScript OOP or: How I decide what gets called when, with “My” constructors

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

Back when I was young I really liked assembly language programming; it was so fast and cool. Then one day I thought:

 Why am I writing a whole page of instructions just to say Hello World? And Task State Segments look really boring and hard. This is too complicated and not fun anymore.

That was the day I switched to C++ and learned about OOP. A little later I ran into PHP. I really liked not having to cast the string ‘1’ to the integer 1; so much faster. No DLL Hell, no installation disks, and PHP programs run on somebody else’s computer!

Now I am having the same experience with Crockford’s new object oriented JavaScript approach with respect to OOP. Back in school they would always make us draw these huge UML diagrams, which were always wrong, and then code to that specification.  Woe be unto you when it needed changing, everything was inter-related. With classless JavaScript objects I don’t have to figure out a classification taxonomy immediately, and then hope I am right, I can just start coding in an easy to understand manner. Odd edge cases are also easier to handle.

The example program below shows how to easily use defaults, overrides, and interfaces. Again, all the internal properties and functions are hung on the hidden member variable:

console.clear();
function checkNewInterface(members, must_have){
  var object_name=members.inheritance_type_list[0];
  for (var property_name in must_have) {
    var must_be_member = must_have[property_name];
    if(!members.hasOwnProperty(must_be_member)) {
      console.log(object_name, "is missing", must_be_member);
    }
  }
}
function privitizeNewVariables(specs) {
  if (!specs.is_private) {
    var members = Object.assign({}, specs);
    members.is_private = true;
    return members;
  }
  return specs;
}
function newAnimal(specs) {
  var members = privitizeNewVariables(specs);
  members.inheritance_type_list = ['Animal'];
  checkNewInterface(members, ['common_name', 'movesBy']);
  var bodyDescription = function () {
    var body_description = '';
    if (members.color_scheme) {
      body_description += members.color_scheme + ',';
    }
    if (members.body_covering) {
      body_description += members.body_covering + ',';
    }
    if (''===body_description){
      body_description = 'none';
    }
    return body_description;
  };
  if (!members.hasOwnProperty('makeOffspring')) {
    members.makeOffspring = function () {
      console.log('Offspring by: asexually')
    }
  }
  if (!members.hasOwnProperty('movesBy')) {
    members.movesBy = function () {
      console.log('Moves by: wriggling');
    };
  }
  return Object.freeze({
    bodyDescription: bodyDescription,
    movesBy: members.movesBy,
    makeOffspring: members.makeOffspring
  });
}
function newSnake(specs){
  var members = privitizeNewVariables(specs);
  members.movesBy = function () {
    console.log('Moves By: slithering');                       
  }
  members.body_covering ='scales';
  if (!members.hasOwnProperty('makeOffspring')) {
    members.makeOffspring = function () {
      console.log('Offspring by: laying eggs')
    }
  }
  if (!members.hasOwnProperty('color_scheme')) {
    members.color_scheme ='brown';
  }
  var an_animal = newAnimal(members);
  var bodyDescription = function () {
    console.log('Animal Body Description :', an_animal.bodyDescription());  
    console.log(' with Fangs');
  };
  members.inheritance_type_list.unshift('Snake');
  checkNewInterface(members, ['common_name']);
  return Object.freeze({
    bodyDescription: bodyDescription,
    movesBy: members.movesBy,
    makeOffspring: members.makeOffspring,
    DANGEROUS_IF: "Red on yellow, deadly fellow"
  });
}
var snorky_specs = {common_name: 'Snorky the snake',
    movesBy: function (){console.log('Moves By: flying is ignored')},
    color_scheme:'blue'};
var snorky_snake = newSnake(snorky_specs);
snorky_snake.movesBy();
snorky_snake.bodyDescription();
console.log('-');
var watersnake_specs = {common_name: 'Northern the Watersnake',
    makeOffspring: function (){console.log('Offspring by: live-birthing')}  };
var northern_watersnake = newSnake(watersnake_specs);
northern_watersnake.makeOffspring();
northern_watersnake.bodyDescription();
console.log('-');
console.log("A snake is dangerous if ", northern_watersnake.DANGEROUS_IF);
var un_named_snake_err = newSnake({});

Here is the console output of the above:

Moves By: slithering
Animal Body Description : blue,scales,
 with Fangs
-
Offspring by: live-birthing
Animal Body Description : brown,scales,
 with Fangs
-
A snake is dangerous if Red on yellow, deadly fellow
Animal is missing common_name
Snake is missing common_name

Explanations:

function checkNewInterface(members, must_have){
  var object_name=members.inheritance_type_list[0];
  for (var property_name in must_have) {
    var must_be_member = must_have[property_name];
    if(!members.hasOwnProperty(must_be_member)) {
      console.log(object_name, "is missing", must_be_member);
    }
  }
}

We can ensure that constructors have a certain set of required values and/or functions in their specifications. The checkNewInterface() function complains if something is missing. For example, the below function call will complain if the variable common_name and/or the function movesBy() do not exist. This occurs above with the un_named_snake_err because it has no common_name.

checkNewInterface(members, ['common_name', 'movesBy']);
members.body_covering ='scales';

Every Snake will have scales because of the above statement, even if another value is in the specifications.

members.movesBy = function () {
 console.log('Moves By: slithering'); 
}

Every Snake will slither, regardless of any other function specified.

 if (!members.hasOwnProperty('color_scheme')) {
   members.color_scheme ='brown';
 }

If any Snake has no color in its specification, it then gets the default ‘brown’ color. Snorky the Snake, however stays ‘blue’.

 if (!members.hasOwnProperty('makeOffspring')) {
   members.makeOffspring = function () {
     console.log('Offspring by: laying eggs')
   }
 }

Northern the Watersnake, uses ‘live-birth’ so the default method of laying eggs is ignored. 

var bodyDescription = function () {
    var body_description = '';
    if (members.color_scheme) {
      body_description += members.color_scheme + ',';
    }
    if (members.body_covering) {
      body_description += members.body_covering + ',';
    }
    if (''===body_description){
      body_description = 'none';
    }
    return body_description;
  };

The above function returns a description of the bodies of the animals if they have color and/or a body covering.

DANGEROUS_IF: “Red on yellow, deadly fellow”

You can even have constants like above.

Part  1  2  3   4  5  6  7

Programming on a Jerker PART 2: Crockford’s New Object Oriented JavaScript Approach or: How I learned to stop using prototypes and learned to love closure

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

The reason that Douglas Crockford’s new Classless JavaScript Objects approach is such a “Good Part” is that it “Avoids the general problem we have in inheritance, that you end up inheriting everything in the past history of an object or a class, this case I only inherit the stuff the I actually need. ” We also avoid the quagmire of building brittle and hard to change classification taxonomies before any reasonable amount of knowledge of the project domain has been obtained. Prototypal inheritance does save memory, but when my cheap android phone has 16gb, it is time to put to bed the old assembly language habit of saving bytes.

Below, version 2 of the evolving example program shows how parent and child objects share functions and variables via the members JSON object. The function Snake.movesBy() is passed into the Animal constructor, and the variable inheritance_type_list is added to members inside newAnimal() so that ‘Snake’ can be added to the front of the list in the Snake constructor.

console.clear();
function privitizeNewVariables(specs) {
if (!specs.is_private) {
var members = Object.assign({}, specs);
members.is_private = true;
return members;
}
return specs;
}

function newAnimal(specs) {
var members = privitizeNewVariables(specs);
members.inheritance_type_list = ['Animal'];
whenInDanger = function () {
try{
console.log('When in danger ', members.common_name);
members.movesBy();
}catch (e){
console.log('Error - whenInDanger() has no movesBy()');
}
};
var isA = function(object_type){
if (members.inheritance_type_list.indexOf(object_type)>-1) {
console.log(members.common_name, 'is a', object_type);
}else{
console.log(members.common_name, 'is not a', object_type);
}
}
return Object.freeze({
whenInDanger: whenInDanger,
isA: isA
});
}
function newSnake(specs){
var members = privitizeNewVariables(specs);
members.movesBy = function () {
console.log('Moves By: slithering');
};
colorScheme = function () {
console.log('Color scheme :', members.color_scheme);
};
aPrivateFunction = function (){
console.log('I only exist inside a Snake object');
}
var an_animal = newAnimal(members);
members.inheritance_type_list.unshift('Snake');
return Object.freeze({
whenInDanger: an_animal.whenInDanger,
isA: an_animal.isA,
movesBy: members.movesBy,
colorScheme: colorScheme
});
}
var animal_specs = {common_name: 'Alf the animal'};
var an_animal = newAnimal(animal_specs);
animal_specs.common_name = "does not change Alf's common_name";
an_animal.whenInDanger();
console.log(an_animal);
console.log('-');
var snake_specs = {common_name: 'Snorky the snake', color_scheme:'yellow'};
var a_snake = newSnake(snake_specs);
a_snake.whenInDanger();
console.log('-');
a_snake.colorScheme();
a_snake.isA('Animal');
a_snake.isA('Snake');
a_snake.isA('Bear');

Here is the console output of the above:

When in danger Alf the animal
Error - whenInDanger() has no movesBy()
Object { whenInDanger=function(), isA=function()}
-
When in danger Snorky the snake
Moves By: slithering
-
Color scheme : yellow
Snorky the snake is a Animal
Snorky the snake is a Snake
Snorky the snake is not a Bear

Explanations:

return Object.freeze({
whenInDanger: whenInDanger,
isA: isA
});

When the Animal constructor returns a “frozen” object, it creates an un-corruptible object that closes over its variables/functions hiding everything except what we declare. The only publicly visible elements of  Animal objects can be seen with console.log(an_animal) which only shows the 2 functions of whenInDanger() and isA(). Complexity, “Let It Go”.


members.movesBy = function () { ...
colorScheme = function () { ... 
aPrivateFunction = function (){ ...

return Object.freeze({
whenInDanger: an_animal.whenInDanger,
isA: an_animal.isA,
movesBy: members.movesBy,
colorScheme: colorScheme
});

The a_snake.aPrivateFunction() only exists inside a Snake object as can be seen by trying a_snake.aPrivateFunction(). This is because aPrivateFunction() is not listed in the Object.freeze() for the public nor added to members for the Animal constructor. Note that the function Snake.movesBy() was added to members to enable Animal objects to use the function. Because Snake.colorScheme() was not added to members, the function cannot be seen be any Animal objects, but it is publicly available.

var isA = function(object_type){
if (members.inheritance_type_list.indexOf(object_type)>-1) {
console.log(members.common_name, 'is a', object_type);
}else{
console.log(members.common_name, 'is not a', object_type);
}
}

The isA() function uses the inheritance_type_list variable to keep track of what types an object belongs to. There is no public access to the inheritance_type_list variable because “Accessors Are Evil!” Note that both Snake and Animal have access to inheritance_type_list because it is attached to the members variable.

whenInDanger = function () {
try{
console.log('When in danger ', members.common_name);
members.movesBy();
}catch (e){
console.log('Error - whenInDanger() has no movesBy()');
}
};

The Animal(parent) function whenInDanger() calls the Snake(child) function movesBy(). WhenInDanger() can call movesBy() since the function is contained in the shared members variable. You can implement something like abstract functions in a similar manner.

function privitizeNewVariables(specs) {
if (!specs.is_private) {
var members = Object.assign({}, specs);
members.is_private = true;
return members;
}
return specs;
}

The function privitizeNewVariables() copies constructor specifications into the members variable the first time it is encountered when building an object in the constructor hierarchy. This ensures that any later changes to the original specs variable do not magically affect the objects built with it. The statement 

animal_specs.common_name = "does not change Alf's common_name";

Does not pertain to the Alf the Animal because a copy, not a reference, was made inside the constructor.

Part  1  2  3  4  5  6  7

Programming on a Jerker PART 1: Crockford’s Classless JavaScript Objects or: How I am over “this” and I am ditching “new”

js_pic_low_rez

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program
JavaScript at their Ikea desks.

I watched this Crockford JavaScript video, at 38:35, and saw something astoundingly brilliant yet simple and obvious.

function constructor(spec){
    let {member} = spec,
    {other}= other_constructor(spec),
    method = function () {
        // member, other, method
    };
    return Object.freeze({
        method,
        other
    })
 }

This is ES6 code, or ECMAScript 2015, which is not available in browsers yet. So it needs to be adapted for normal JavaScript use in browsers.

I looked for explanations and found this half-done gist.  It took a while for me to understand it and yes it is definitely a JavaScript “Good Part”. Here is the best part; The code makes sense and is very easy to manipulate.

You will notice there are no uses of “this”, therefore no loss of “this” context. No “new” to be seen anywhere. The abomination “object.prototype.constructor” does not rear its ugly head either. Here is an example, and yes, in the later parts of this series a duck-billed platypus, a mammal, is gonna lay an egg.

The function newAnimal() is the Animal constructor, and newSnake() serves to construct Snake objects.

console.clear();
function newAnimal(specs) {
var members = Object.assign({}, specs);
var commonName = function () {
console.log('Common Name :', members.common_name);
};
reproductionSystem = function () {
console.log('Reproduction System: asexual');
};
return Object.freeze({
commonName: commonName,
reproductionSystem: reproductionSystem
});

}
function newSnake(specs){
var members = Object.assign({}, specs);
movesBy = function () {
console.log('Moves By: slithering');
};
var an_animal = newAnimal(members);
return Object.freeze({
commonName: an_animal.commonName,
reproductionSystem: an_animal.reproductionSystem,
movesBy: movesBy
});

}
var an_animal = newAnimal({common_name: 'Alf the animal'});
an_animal.commonName();
an_animal.reproductionSystem();
console.log('-');
var a_snake = newSnake({common_name: 'Snorky the snake'});
a_snake.commonName();
a_snake.reproductionSystem();
a_snake.movesBy();

The console output of the above code.

Common Name : Alf the animal
Reproduction System: asexual
-
Common Name : Snorky the snake
Reproduction System: asexual
Moves By: slithering

There are still a few things to be fixed with this implementation. For one, parent functions(Animal) cannot call child functions(Snake) yet. There are no default values/functions, no interface tests, nor any overriding. But everything looks and works as expected.

Note that IE needs a polyfill for Object.assign().

Part  1  2  3  4  5  6  7