Understanding JS: Notes 4 (Objects and Functions)

Computed member access operator aka []: person[‘firstname’]

Member access operator aka dot . operator: person.firstname

Object literals: using {} to define a new object (this is the preferred way rather than using new Object)

Framework aside

Namespace: a container for variables and functions, typically to keep variables and functions with the same name separate. This doesn’t exist in JS.

Faking namespaces is when we use objects to contain other functions/variables that may collide due to having the same name. This occurs often in frameworks and libraries.

The good thing about this is we can do as many levels as we want, but we have to be careful with using the dot operator or [] when we put things inside. If we were to do something like <code>english.greetings.greet = ‘hello!’;</code> We would get a type error saying we cannot set the property of ‘greet’ of undefined. Why? This is because the dot operator runs left to right. So first it runs english.greetings and finds that this thing doesn’t exist aka undefined. So it cannot create a greet property on something that is undefined. We would have to have something like <code>english.greetings = {}</code> first.

JSON: JavaScript Object Notation is inspired by object literal notation in JS, BUT IT IS NOT THE SAME. Before, people used to send data on the internet via xml. Which was fine, but it can be rather data intensive. If you wanted to say an object, you would have to have syntax like







This is generally fine if a lot of people are downloading this information, but imagine if you a lot of people needed this info. To send one piece of information, you need an object tag and also two firstname tags. That can be a lot of wasted bandwidth. So people started to adopt JSON which was again inspired by JS objects but with some changes. First, object properties HAVE to be wrapped in quotes, where that is not necessary for JS objects.

First class functions: everything you can do with other types you can do with functions. Assign them to variables, pass them around, create them on the fly.


As we already seen, objects can have references to primitives, objects, and other functions, but functions are special types of objects with two special properties. The first is the name, which is optional. The second is the code. The code within a function belongs to the code property of a function and it is invokable or callable.

Expression: a unit of code that results in a value. It doesn’t have to save to a variable. Ex: a = 3, 1+2, var obj = {greeting: ‘hi’}, etc all return values.

Statements: statements do not return values. Ex function declarations do not return values and therefore are statements. Things like if statements are also statements because that unit of code in particular doesn’t return a value.

There are function expression and there are function statements.


function greet () {




This is a function statement.


var anonymousGreet = function() {




But this is a function expression, because the function part returns a value aka an object being created which is then referenced by the var.

The important thing to remember about using function expressions is that if you try to call the function before it is defined, then you’ll get a type error. The function is not hoisted because during the creation phase all it sees is var anonymousGreet and sets it to undefined like all variables.

Conceptual Aside (by value vs by reference)

By value is when we have a new variable set to a previous variable and the engine makes a copy of that value at a new location. Where as by reference is when in JS, if we copy an object the new variable doesn’t create that object again in a new location, but rather sets the new variable to the same reference as the first. Both variables then point to the same object.

Mutate: to change something (immutable means it can’t be changed)

If we mutate object a, b will also reflect that update because they point to the same object in memory.


Every time a function is called the JS engine also creates <code>this</code>, but depending on the circumstance it can point to different things which can be both confusing.

When you just invoke a function, this refers to the global object.

What about when you create a method? (A method is a key / value pair where the value is a function).

In this context, this refers to the object where the method lives.

So what about a function that gets defined in a function?

Here this actually refers back to the global object and not the c object. Lots of people think this is a bug and is wrong. One way to avoid this error is to create a new var (like self) and use it to reference the original this. And then use that throughout the object to ensure that self refers to what you want it to.

Array: a collection of anything. In JS, you can mix and match the type of vars inside.

‘arguments’ and spread

During creation phase, the execution context also creates a keyword arguments (this is changing in es6). Arguments are the parameters that you pass to a function, but JS creates a special keyword arguments as well. In JS, if you don’t pass parameters to a function, it doesn’t say there’s an error, rather the JS engine sets up the vars and makes them undefined. In ES6, you are able to designate default parameter values in the function declaration.

But in previous versions, you can set the up by defining your parameters in the function using the || operator.

The arguments keyword is an array-like variable that lists all the arguments passed in an array-like structure. People say array-like because it looks like an array, but it doesn’t have all the features of an array. It will eventually get deprecated and changed to something called spread. Spread is the …other parameter which will wrap up any other arguments into an array, but it is not completely available yet.

Function overloading: in some languages, functions can have the same name that have different number of parameters. This doesn’t exist in JS, but it really doesn’t matter. There are ways like setting up default parameters or creating other functions that send default parameters that can mimic this idea.

Dangerous Aside

A syntax parser reads your code character by character and tries to understand what you’re trying to do and if that’s valid JS. It can then also modify your code to guess what’s happening.

Automatic semicolon insertion: So you may have noticed that semicolons are optional in JS code, but they’re not really optional. The syntax parser is reading your code and if it expects a semicolon but sees a “return” then it will automatically put in a semicolon for you. So it’s not really optional, it’s just done for you. The suggestion here is that you should always put semicolons where you want them to avoid errors.

By putting this object on the next line of a return statement, the js engine auto puts an semicolon in, thus ending your code. To fix this, you have to put the curly brace on the same line as the return to tell the JS engine that you started a new object.

Whitespace: invisible characters that create literal space in your written code. This can be used effectively to create more readable code.

Immediately invoked function expressions (IIFE): Adding () after defining a function invokes the function expression. To do it without putting the value in another variable, you have to wrap the function in parentheses. Why? Because if the JS engine sees function then it expects a function statement. If the JS engine sees () first then it’s going to expect an expression like (3+4). We can use IIFEs to wrap functions and make sure variables don’t interfere with or overlap with other functions or variable declarations of the same name. So in many libraries or frameworks, you’ll see that they wrap all their code in an IIFE so that if they have a var like “name” it exists only in the execution context of their library and not interfere with other code that you wrote. This way, when we write code, we don’t accidentally add things or collide with code in the global object. If we wanted to, we still could by passing a parameter but when we do, it will be intentional rather than accidental.

Understanding Closures

So we know when a function is run, it creates a new execution context. In this example, we see that greet returns a function, but it is a function expression. It is not run yet. The function doesn’t get run until the JS engine reaches <code>sayHi(‘Tony’)</code> At this point in time, the greet execution context is gone, but the sayHi execution context still has access to the whattosay variable. Why? Because JS supports closures and makes them for you. So even though the execution context is gone for greet, the variable whattosay is still available in memory, and any function that was created inside another function has access to its parents variables even though the execution context for the parent is gone. Closures is how the JS engine keeps all of the local variables a child function should have access to even if their parent execution context is gone.

Framework Aside – Function factories

When a function returns an object (functions are also objects), then we call them function factories. Every time we call makeGreeting, we make a new function that has its own closure/execution context. This allows us to make functions from functions like greetEnglish or greetSpanish that because of closures still has access to the original language parameter, even though that execution context is gone. all

Callback function: a function you give to another function to be run when the other function is finished.

call(), apply(), and bind()

These methods help designate what <code>this</code> will be in the execution context. All functions have access to these three methods.

logName will return a type error because this refers to the global object which doesn’t have a getFullName function. If we want to control what the this keyword points to, we can use bind to force this to be the object that we want to be the this variable. When we use bind, it creates a copy of the function that was created on the fly.

If we do logName.call(person) we invoke the function but also can designate what the this variable should be. In this case, we could also do something like logName.call(person, ‘en’, ‘es’). Unlike bind, call doesn’t create a copy of the function, it just invokes the original function and runs it using the this that we designated.

logName.apply(person) does the same thing as call but you have to pass an array of arguments (ex: logName.apply(person,[‘en’,’es’])).

With bind, we make a new copy of the function. If we set parameters, we permanently set the parameters for that function. If we only pass one parameter, then the first parameter will be set to that value by default. This is called currying.

Function Currying: Creating a copy of a function but with some preset parameters. Often useful with mathematical functions.

Functional Programming

Introduced in this part briefly, FP is basically a way of thinking about how to code that leverages the benefits of first class function programming languages. If done well, it can help make our code more usable and sharable. Many libraries adopt principles of functional programming. From some reading of (https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0) there are some clear principles of what FP should be. First and foremost is pure functions. Given a set of arguments pass to function, the result should always be the same. It shouldn’t vary based on where the code is or when it’s run. In that same vein, it avoids things like shared state and mutating data.

I’m probably going to do some more reading about this later, but that’s the end of this part on objects and functions. It took a few days to get through, but there was definitely a lot of material.