Category Archives: javascript

Pure prototype inheritance with Object.create

Say I want a bunch of robots to have a common base. They should all have some kind of common base attributes and functionalities. Specifically, their names should be ‘default’, and they should be able to greet people.

Hence, we’ll first create an object with those commonalities first:

Now let’s create a robot that inherits from our object.

if you were to log robotA, you’ll see that its own object is empty. However, its prototype object (__proto__) is that of our robot object. Thus, letting us be able to use those functionalities


{}
__proto__:
greet: ƒ ()
model: "Default"
serial: "000000000"
__proto__: Object

We can do robotA.greet() and we’ll get


"hello, my name is: Default 000000000"

Additionally, you can over those properties and methods in your prototype object. In our case, we can over-ride the firstName and lastName properties to name our robot-like so:


"hello, my name is: R2 D2 3000, 294SFW939sS"

Object.create

Polyfill

Polyfill is code that adds a feature, which certain engines lack. For example, older browsers have older JS engines. They may not support certain functionalities.

Built-in Function constructors

A string primitive is a string literal like so:

However, we can also create String objects like so:

This ‘a’ string, not a primitive. It was created using object String. Thus, when you
display it, you’ll see that it has many properties 0, 1, 2, with their values as 0: “B”, 1: “o”, 2: “b”.

Its length is 3.


String {"Bob"}
0: "B"
1: "o"
2: "b"
length: 3
__proto__: String[[PrimitiveValue]]: "Bob"

When you’re using function constructors to create Strings, Numbers, etc, you are creating Objects.

Add features to all String objects

if we invoke a function on a string literal, JS converts the string literal to a String object automatically:

However, we can’t do this for Number objects.

Danger

For example when we use value comparison ‘==’ between primitive 3 and Number object 3, it will compare the values 3, and give you true

However, === compares values AND types. So in this case, it would give us false

Array object dangers

Because for Array objects, the indexes (0, 1, 2, …n) become properties of the Array Object. Their values would be the data in the array.

However, this presents a problem. When we use for-in to loop through arrays, it goes like this:

print out prop, and you’ll get string type index “0”, “1”, “2”…etc. These are properties of our Array object.

However, if we were to add properties to Array prototype, it would also show.

if you were to use the for..in loop again, you’ll see the property:


ricky
joy
En En
hahah

In order to combat this, we can use hasOwnProperty. First we have to check to see if the array’s string type indexes are its own property.

We see that it is. Our haha propety belongs to the prototype object, and not of the array object itself:

Thus, when using for..in, you’ll have to add a check to display if the property is the object’s own.

…or you can also simply use the original for loop like so

function vs new (js)

ref – http://chineseruleof8.com/code/index.php/2018/02/06/prototype-and-inheritance-in-js-non-class/

When we declare a function in a js file, the ‘this’ is set to the global object.

When trying to access properties that do not exist, the property gets added to the global object.

In our case, as you can see, the ‘this’ inside of function Person is referencing the global object. We access userName, but it does not exist, so it gets added to the global object. Then we assign ‘name’ to it.

Thus, after invoking Person, global.userName will be ‘ricky’.

However, when we use ‘new’ in front of the function, the function becomes a constructor. The ‘this’ inside the function is an empty object with the name ‘Person’.

Finding that property userName does not exist, it will add userName to Person {}, and assign parameter name to it, becoming: Person { userName: ‘ricky’ }

Here’s why this happens.

A function constructor an object. All objects have a ‘prototype’ property. A function constructor will also have a property called ‘prototype, which references a ‘prototype object’. So in our case

…and if we go a step further, we come to the prototype chain.

Why do we add properties and functions to the prototype object?

Se added function property fullName to Person’s prototype object. We declare properties in the prototype object because all instances share it. This saves memory. Whereas if we were to declare it in the function constructor, then every instance would have that copy. If we were to have 1000 instances, then we’d get 1000 fullName functions. This would take up too much memory.

Dangers of ‘new’ and Function

Sometimes, we forget to use new and just use the function instead, like so:

Under this situation, me is undefined because we ran Person as a function.
Thus, we’ll get an error.

What happens when ‘new’ is used

1. New {} is created
2. function is called, this = {}, properties get attached to {}
3. {} linked to prototype via _ _ proto _ _ property. It now points to the prototype object.
4. function automatically return {}

Another Example

Async operation explained in terms of Creation/Execute Phases

Given this code snippet, it invokes a function greeting, which in turn invokes an async function setTimeOut. After two seconds, we then execute an anonymous function.

Let’s see how this works in memory.

When the program starts up, the global context is invoked. When something is invoked, it goes through creation and execution phase.

Global context Creation Phase:

– this reference the global object
– outer scope is set
– stores ‘greeting’ function into memory. Thus hoisting it.

In Global context Execution Phase, we start executing each line of code. We see the definition of the greeting, we move on. We then see greeting is invoked. We push that onto the execution context.

When a new context is pushed onto the execution context we have to process its creation phase and execution phase.

So do this for greeting function.

Greeting Creation Phase:

– this references global object
– sets up outer references
– puts variable name in memory and assign it to undefined

Greeting Execution Phase:

We see that variable ‘name’ gets assigned to “Bob”.
We then invoke setTimeOut function. Its definition is already in the JS library.
Thus we push setTimeOut context onto the main execution context.

Whenever a new context is pushed, we have to process its creation and execution phase.

setTimeOut Creation Phase:

setTimeOut has parameter which is an anonymous function. We put that into memory.

Because setTimeOut is an async function, it may need to be running even if its parent function has been popped from the execution stack. So in order to remedy this, it gets put into memory.

Now that the creation phase of setTimeOut is done, we continue with setTimeOut’s Execution Phase.
It executes starts running its timer for two seconds. Because this function is running async, we continue executing down the line even though the timer is still running. We get to the end of ‘greeting’ and its context pops from the execution stack.

However, even though ‘greeting’ has popped, notice that its variable ‘name’ has not. This is because the callback anonymous function we put into memory references that ‘name’ in its console log statement. Hence, we keep greeting’s name variable in memory.

Two seconds later, the timer is done. The anonymous function then gets pushed onto a queue called The Callback queue
Because the execution stack is empty (no other custom function or Web-based functions are running), we are then able to push our callback function from the Callback queue and onto the execution stack.

As with any new invocations on the execution stack, we must go through Creation and Execution phase.
During the creation phase, the ‘this’ reference is set to TimeOut object because setTimeOut is a reference to a function constructor object TimeOut. There are no parameters, declared variable(s), or function definitions to be placed in memory.

In the execution phase, we start executing the console log statement. It calls on the name variable. That name takes on the value from greeting’s name variable which is currently pointing to Bob. Thus, the anonymous function’s name points to string literal “Bob”.

When we’re done, the anonymous function pops, along with its variable name because no other is referencing them. Since callback of setTimeOut(callback) has been garbage collected, setTimeOut itself has nothing to do in memory so it gets garbage collected as well.

Greeting definition is still in memory because it was previously defined and needs to be used. Its variable ‘name’ is not used by anyone so it will eventually be garbage collected as well.

Async operation explained generally

1) We execute function first and push it onto the stack.
2) We then execute the log function and print “Hey There”.

1) logging finishes and gets popped. Our string gets garbage collected from memory
2) function second gets executed and pushed onto the stack.

1) setTimeout gets pushed because it was executed.
2) Because it runs asynchronously, it gets put into a different part of memory reserved for async operations

1) function seconds finishes and pops
2) log “The End” gets pushed onto the stack

Logging of “The End” gets popped from stack.
function first gets popped from the stack.
“The End” gets garbage collected from the heap.

Our async operation finishes, and the callback function gets pushed onto a “Callback Queue”.

We see that the stack is empty. Thus, we can push our callback function onto the stack to be executed.

The callback function executes. We push the log function onto the stack. Its string gets moved to the heap.
We then print.

Then the string literal gets garbage collected.

The log function gets popped,
The callback function gets popped,
and everything returns to empty.

Closure Factory function

How Closures work when we return functions.

First, we push the global execution context onto the stack.

We start with the Creation Phase of global and place these things into memory:

– ‘this’ references the global object
– sets outer reference
– makeGreetings function definition
– var greetEn = undefined
– var greenSp = undefined

Then in the Execution Phase of Global, we go down line by line.

makeGreetings is a function definition which was already taken care of in the creation phase. greetSp is already in memory. Then we see code line //1 )

It’s an invocation. We push this execution onto the stack.


The invocation has parameter ‘language’ that references literal string ‘en’.

For Creation Phase of makeGreetings, we put variable ‘language’ in memory. We set the ‘this’ reference to the global object. Set the outer reference. Then we put the whole anonymous function in memory.

Now, we do the Execution Phase of makeGreetings. It doesn’t do anything and simply return the anonymous function that is in memory.

We finish processing makeGreetings(‘en’) and gets the returned anonymous function, we point our greetEn reference to it.

We then move on to code line // 2)

At this point, makeGreetings(‘en’) pops from the stack because it has finished execution.

Now we come to code line //3

It is an invocation of function greetEn(‘bob’) so we push it onto the execution stack.

For greetEn’s Creation Phase, we have a parameter so we put name = ‘bob’ in memory.
– The ‘this’ references the global object.
– We set the outer reference

In its greetEn’s Execution Phase, it will first look at variable language to see what it is. In memory, variable language is referencing a literal string ‘en’. It will then trigger the if statement and we execute the log statement.

We see that the log uses variable name. In memory, name is ‘bob’. Thus we log out:

‘Hello Bob my friend’.

After greetEn finishes, our execution moves on to the next line and greetEn is popped from the stack.

greetEn execution context is popped from the stack.
parameter ‘name’ is popped along with greetEn execution stack because no one else is referencing it.
var greetEn is still referencing the anonymous function in memory.
language is still there and set to ‘en’.
makeGreetings function definition is still in memory.

semi colon insertion

IN this situation, you’ll get undefined because a break after the keyword return makes JS gives you an automatic semicolon. It thinks that because you have a bracket on the next line, this is a line-break and will automatically insert a semicolon for you.

To remedy this do this:

Objects, functions, and ‘this’

Execution Context (Creation Phase)

– variable environment
– reference to the outer environment. It will keep stepping outside of its parent environment until it finds what it is looking for.
– ‘this’ variable. Will be pointing to a different object depending on how this function was invoked.

There are a few scenarios which change the ‘this’ variable depending on how the function is called.

Let’s take a look at a couple of these scenarios:

this in standalone functions

In es5, when you create a function, the ‘this’ inside of the function references the global object.

You can crash into the global namespace by using the ‘this’ in es5.

this in literal objects

If the function is attached to an object, the ‘this’ i referencing the object that the function belongs to.

‘this’ of Inner functions of object functions point to global

Now, functions of functions will have it’s ‘this’ pointing to the global object. Thus, when you use ‘this.name’, the this references the global object. You try to access property name which does not exist, so it then adds the name property for you. And assigns it to a literal string “hehe”.

Hence, you have not touched your object c at all. Instead, you’ve manipulated the global object.

There are 3 solutions to this:

Using Function’s prototype methods call

All function object can use prototype methods call, apply, bind.

call invokes the function. It also lets you decide what the ‘this’ variable should be. It let you’s control which Object the ‘this’ inside of the function points to.
‘call’ actually executes the function.

Finally, if you use es6, you can use the arrow function.

JSON and object literals

In the older days, we send packets of data across the network using XML like so:

The issue here is that our tags ‘firstname’ takes up too many characters. For one piece of data, we’re sending a property name twice.

Then they looked at how JS does its key/value convention and adopted that because it saves space.

Hence, nowadays, we send packets via JSON.

However, there are rules for JSON: property needs to be wrapped in quotes

JS does come with built-in function JSON.stringify.

JSON.stringify will convert any JS object into a JSON string.

And if we have a JSON string, we can use JSON.parse() and convert it into a JS object.

output


{ "name": "mary", "isProgrammer": true }

typeof JSON.stringify(obj) will give you “String”.

If we were to parse JSON string into a JS object, we first have to make sure its valid JSON.
Make sure you put quotes around the properties and make the whole thing into a string.


{name: “mary”, isProgrammer: true}

Faking a Namespace

A container to keep variables and functions. Typically it keeps functions and variables (with the same name) separate.

One way to separate them is to use object literals.

Hence these variables become containers to make sure names do not collide with others.