Tag Archives: udemy

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.

Objects, dots, and literals

Dot operator

Objects are a collection of name/value pairs.

let object = {
address: {…},
name: “rick”,
display: function() { console.log(name + address.toString()); }
}

Using references (names), it can contain values:

– primitive
– object
– function (methods)

The objects sit in memory via a hex address. For example 0x294abcc9
The references also have a reference. For example, in our example above, object, address, name, display all are sitting on hex address memory.

Below, we create a new object have a reference ‘name’ point to it.

Then using brackets, we’ll specify a string that designates the name of the property we want to add. This is called computed member access.

For the property, we give it firstname.

Therefore, ‘firstname’ is now a property of our person object. It also is sitting on a hex memory. It is referencing a string literal with data “Rick”.

You can use another variable as a placement.

However, there is a cleaner operator on how to do this. And its called the “dot” operator.

The dot operator is a function:

It takes firstName as the string parameter and uses it as the string with computed member access.

Associative is left-to-right

When you use dot operator, its associative priority is left to right.

In our example, it’ll look at obj and then try to find the next string as a property. Hence, it’ll see obj, and try to see if it has an address property. We attached an object literal to the address property already so it finds it. Then it looks at the property name. However, ‘name’ is nowhere to be found so it attaches the ‘name’ property and assigns it to literal string ‘haha’.

console.log(obj.address.name); // haha
console.log(obj[“address”][“city”]); // nowhere

Object Literals

Object literal is the same as ‘new Object’. It creates a single instance of an object.

It is created like so:

this is essentially same as

You can also have nested objects like so:

Now, we can pass these objects into function parameters to be used. This is because function parameters take references to objects. Thus, when you pass in this literal object, you are literally giving it the object reference. That is why you can pass in whatever object you want, and then use that object within the function.

You can also create literal objects on the fly in the function parameter space like so:

You are creating something on the fly when the function is called.