Prototypal Inheritance and you.

Let’s first start by saying that Javascript is a little interesting when it comes to classes and objects. Technically I think Javascript is basically classless (probably why I like it so much…) but there are class-like activities. Just remember at its root, an Object is a just a unordered collection of key:value pairs. Anything other than strings, numbers, booleans, undefined and null is an object.

Let’s create some objects.

var anObject = {};
anotherObject = new Object();

-or-

function MyObject() {}
var myObject = new MyObject();

 

Now where does Prototypal Inheritance enter into this? Each object has an internal link to another object, known as its prototype.  This other object also has a prototype, and so on until we reach null as its prototype.null ending the chain.

Objects are buckets of properties with links to a prototype object. When access to a property is requested it will look not only at the specific objects property but all the way back up the prototype chain until the property is found or the end of the chain.

Let’s add some methods to the objects.

function MyObject() {}

var myObject = new MyObject();

MyObject.simpleLog = function(value) {
    console.log(value);
}

var difObject = new MyObject();

difObject.simpleLog = function(value){
    console.log('The value is: ', value);
}

difObject.simpleLog("something should go here"); //calls the instance specific method
MyObject.simpleLog("something should go here"); //calls the static Object method
MyObject.prototype.simpleLog = MyObject.simpleLog; //apply the static method to all instances from here on in
difObject.simpleLog("still calling instance method");  //still calls the instance method
var yetAnotherObject = new MyObject();
yetAnotherObject.simpleLog("inherited from MyObject"); //inherited simpleLog() from MyObject
MyObject.simpleLog("I also inherit."); //pre-existing instances also inherit the new function

 

So as you can see when you add a method to the prototype it gets inherited along the prototype chain. There is an order to when this gets used as you can see in the difObject.simpleLog(); call that it uses the local instance method as it does not have to go up the chain to find the one we added with the line MyObject.prototype.simpleLog = MyObject.simpleLog;

Now when we reference methods in JavaScript it is not strictly accurate in the form that other class-based languages. For JavaScript any function that you add as an object property becomes a method for that object.  An inherited function acts just as any other property on that object, including method overriding!

Another key point to remember is what happens to this. Its value points to the inheriting object not back to the prototype object where the function is an own property. Let’s look at another example.

var myObject = {
    staticValue: 40,
    someMethod: function(val) {
      console.log(this.staticValue);
      return this.staticValue + 1;
    }
};

console.log(myObject.someMethod()); //42

var yourObject = Object.create(myObject);

yourObject.staticValue = 20;

console.log(yourObject.someMethod());  //21

 

As you can see once we overwrite a value it will no longer work its way up the chain allowing for differences in the objects after they are created. Very useful! I will be digging deeper into objects and modules in another post.

YDKJS Types & Grammar

Chapter 2 “Values”

Javascript has some interesting aspects to arrays, strings and numbers! In this chapter we explore them in a little more detail.

Arrays

Javascript arrays are not type-enforced. They can contain strings, numbers, objects, even other arrays aka multi-dimensional array.

var myArray = [ 1, "1", {1:"One"}, ["Juan"] ];

 

Arrays also do not need to have their size predefined. You can just declare and add willy nilly. There is some care when using delete on an array because it will remove the slot, but even if that slot is the last element it does not update the length property of that array. Also watch out for “sparse” arrays by creating empty or missing slots. This can lead to some unintended consequences when dealing with the array values.

Another odd thing is that since arrays are also objects you can have string key/property values added to them, but this does not change the value of the length of that array, unless that value can be coerced into a base-10 number!

var myArray = [ ];
myArray[0] = 1;
myArray["crazytown"] = 42;

myArray.length == 1; //true
myArray["crazytown"] == 42; //true
myArray.crazytown; //42

//watch out for numbers!

var myOtherArray = [ ];
myOtherArray["42"] = "crazytown";
myOtherArray.length == 43; //true 

 

Interesting ES6 built-in called Array.from(…) It can do more that I will have to learn about!

var arr = Array.from( arguments );

 

Strings

At first glance one might think that strings are just arrays of characters. Strings have a length property, an indexOf method and even a concat method. So they are the same right? Not so fast! JavaScript strings are immutable, while arrays are! Look at the following:

myString = "ramen";
myArray = [ "r", "a", "m", "e", "n" ];

myString.length == myArray.length; //true

myString.indexOf( "e" ) == myArray.indexOf("e"); //true

//however watch this

myString[1] = "X";
myArray[1] = "X";

myString; // "ramen"
myArray; // myArray = [ "r", "X", "m", "e", "n" ];

 

If you find yourself treating strings as arrays, consider using just an array. You can always join the array back up if you need to use it as a string.

Numbers

Unlike many other programming languages javascript has only one flavor of numeric datatype. number. This number contains integer(ish) numbers and fractional decimal numbers. The ish above is because the integers are just not exactly as you would expect. Google has a ton of examples, here is one. Trailing and leading 0’s are removed from decimals 0.42 becomes .42 and 4.200 becomes 4.2 etc.

Another interesting thing is that numbers get access to the Number.prototype methods, like toPrecision() and and toString(). Some caveats when using them. If you tried 42.toString() returns invalid because the initial . is considered to be a part of the 42, you can get around this by using parentheses (42).toString() or 42..toString(). Things have changed a bit for octal literals in ES6 and/or strict mode so that 0363 no longer equates to 243 instead you would use 0o363… very fun.

You can also get whonky stuff like 0.1 + 0.2 === 0.3 returning false… There are ways around this, ES6 has some specific tools for this (see Number.EPSILON). ES6 also has Number.MAX_SAFE_INTEGER (9007199254740991) and Number.MIN_SAFE_INTEGER (-9007199254740991) it also has an isInteger test that you can polyfill by checking typeof num is “number” and its % 1 is 0. It gets deeper with ES6 as you can use .isSafeInteger

Numbers are strange, mmmkay.

Special Values

I like these. They are special! They are null, undefined, and void . null being an empty value and undefined being a missing value. null is a keyword making it have a sort of protection field around it so you can assign null to something. undefined can be, at least in non-strict mode, you can do bad things like setting undefined to equal something! Just don’t do it!

Void is an interesting one, I have dug around and I don’t think I know why I would use this. I am sure as I get deeper into javascript I will figure it out.

Special Numbers

NaN, not a number… even though the typeof for a NaN is a number… mmm bad naming conventions. I have learned to think of it as just being a bad number. It happens when you try a mathematical expression using something that is not a number. Another interesting quirk about NaN is that it is not equal to itself! so NaN !== NaN… kooky. Using this we can create an interesting polyfill to check to see if something is NaN.

if (!Number.isNaN) { //if the browser does not have access to this
    Number.isNaN = function (n) {
        return n !== n;
    }

 

Cool! I will have to make sure I start putting this in!

To Infinities and beyond! Okay not beyond, but right to them! Basically this means you can make a value that is just too big (or too small) for JS to deal with and it assigns it Infinity or -Infinity. This leads us to another special case in javascript…

Zero or 0 or -0?

Javascript has both a 0 and a -0. What makes it even more difficult is that 0 == -0. Another helper function pops up!

function isNegZero(n) {
    n = Number( n );
    return (n === 0) && (1 / n === -Infinity);
}

 

Again I think I need to get deeper into code to see why this would matter. For now I will just keep it in the back of my mind.

Special Equality

When we need to check for these special equalities ES6 gives us a tool to help. Object.is() to the rescue. So now Object.is( 0, -0); returns false! Wahoo! Save Object.is for special occasions where you might need to check this!

Value vs. Reference

A reference in javascript points to a space in memory so if you have multiple references to this space in memory they do not reference each other. Only the type of the value designates whether the value is assigned by copy or by reference.

Scalar Primitives are always assigned by copy: null, undefined, string, number, boolean and symbol.

Compound values such as objects and functions always create a reference copy on assignment or when passed.

 

This and That, mostly this.

The question of “What is this?” can be a tricky one. Even outside of programming context is required. Can I see it? Do I know who is asking me? Is it blue? Let’s focus in on what it means in computer science, even more specifically what does it mean in Javascript?

Mostly this has a value that is determined by how a function is called. We also know it can’t be set by assignment during execution. It can also be a different value each time the function is called. What have we learned so far? It is all about context. There are options such as bind
to set the value inside a function regardless of how it was called. There are also some ECMAScript 2015 ideas called arrow functions where this
is lexically scoped (it is set to the this value of the execution context closure).

Still not super clear. Time to dig a little deeper.

Starting with the global context.

Open the developer console and type this. You get a huge object. With so many properties that it is not easy to visually parse. Looking at a few of the more familiar ones what do we see?

this.Array === Array; // true

this === window; // true

this.a = 37;
this.a === window.a; // true

As we see the value of this in the above context is the global object (window in the case of a browser). How does this change in a function?

function thisFunction1() {
  return this;
}

thisFunction1() === window; //true

function thisFunction2(){
 "use strict";
  return this;
}

thisFunction2() === undefined; //true

Since in thisFunction1() this is not defined by the call AND because its not in strict mode the value of this defaults back to the window option. We see in the second example thisFunction2() the value of this remains at the value set when entering the execution context. If it is not defined we get… undefined!  It’s getting a bit more clear, I can still read through it though.

Arrow Functions? I have recently become a huge fan of arrow functions. They are clear to read, shorten my code and now I can more easily understand what this would be during function execution.

It looks like when you initially define the this value it will stick. It will also be set for any calls to functions that live as object methods if the object method is an arrow function. There is a great example on developer.mozilla.org Even functions within functions the this value stays tied to the outer execution context.

More on object methods, not just fat arrow style.

var objectWithMethods = {
  someValue: 42,
  usefulMethodName: function() {
    return this.someValue;
  }
};

console.log(objectWithMethods.usefulMethodName()); // logs 42

 

When making a function that will be used as a constructor with the new keyword its this will be bound to the new object.

More on this later!