Ellatronic
Design Portfolio

Blog

Posts in Coding
JavaScript: Understanding the Weird Parts (Part 9)

Whitespace

  • whitespace - invisible characters that create literal space in your written code, carriage returns, tabs, spaces
    • Whitespace can be used liberally to clarify code in the form of comments.

Immediately Invoked Function Expressions (IIFEs)

var greeting = function(name) {
    console.log('Hello ' + name);
}();
  • Using parenthesis invokes the function immediately after creating it (IIFE).
  • When the function is invoked, it returns a value that gets set to greeting.
console.log(greeting); // -> Hello undefined
  • Pass a parameter in the parenthesis of the function call to produce a result instead of undefined.
  • Turn a function statement into a function expression by enclosing it in parenthesis.
(function(name) {
    var greeting = 'Hello';
    console.log(greeting + ' ' + name);
}()); // IIFE
  • This is a popular style present in many frameworks today.

IIFEs and Safe Code

  • Variables created inside the IIFE do not touch the global execution context.
  • In source code, all the code is typically wrapped in an IIFE in order to ensure the code does not collide with other reusable pieces of code.

Understanding Closures

function greet(whatToSay) {
    return function (name) {
        console.log(whatToSay + ' ' + name);
    }
}
greet('Hi')('Ella'); //->Hi Ella
var sayHi = greet('Hi');
sayHi('Ella'); //-> Hi Ella
  • After the greet function finishes executing it gets popped off (goes away) but the whatToSay = 'Hi' is still in memory, so the sayHi() function can go down the scope chain to find whatToSay = 'Hi'.
  • Closures are a feature of JavaScript that make sure a function has access to all the variables it needs.
JavaScript: Understanding the Weird Parts (Part 8)

Arrays: Collections of Anything

var arr = [1, 2, 3];
  • JavaScript arrays are 0 indexed; they start at 0.
  • Since JavaScript is dynamically typed, we can mix and match types within an array.

arguments and spread

  • arguments - the parameters you pass to a function
    • The keyword arguments is a special term JavaScript uses to contain all the arguments.
    • arguments contains a list (that looks like array) of all the values of parameters that have been passed.
function greet(fname, lname, ... other) {}
  • Additional parameters that are not explicityly defined in the function call get wrapped up in a array other.

Syntax Parsers

  • Syntax parsers read the code and decide if it's valid, and determine what the code is trying to do.
    • They go through the code character by character.

Automatic Semicolon Insertion

  • Semi-colons are optional in core JavaScript.
  • carriage return - finishing a line, hitting return on the keyboard is an invisible character but the syntax parser can see it.
    • If you use a carriage return, the syntax parser will automatically inject a semi-colon.
  • The syntax parser automatically inserts a semi-colon whereever it expects one to be.
  • So, always insert your own semi-colons.
  • Don't use a carriage return after return if you want to return something after.

Do:

return {
    name: Ella
}

Don't:

return
{name: Ella}
  • See how the Do includes the { right after return, while the Don't uses a carriage return after return.
JavaScript: Understanding the Weird Parts (Part 7)

Objects, Functions, and this

  • this can be changed depending on how the function is called
function a() {
    console.log(this);
}
a(); //-> window
  • When you create a function statement or expression, this still points to the global object if you are simply invoking the function
var b = function() {
    console.log(this);
}
b(); //-> window
  • Even though there are 3 execution contexts (global, a, b) and they all get their own this keyword, all the this keywords point to the same address in the computer's memory (the global object).
var c = {
    name: 'The c object', //property (primitive)
    log: function() { //method (function)
        console.log(this);
        }
}
c.log(); //-> 'The c object'

var c = {
    name: 'The c object',
    log: function() {
        var self = this;
        self.name = 'Updated c object';
        console.log(self);
        
        var setName = function(newName) {
            self.name = newName;
        }
        setName('Updated again! The c object');
        console.log(self);
    }
}
  • use var self = this at the beginning of the function.
  • self and this are both objects so they are going to be set by reference (each point to the same location in memory).
  • Change this to self everywhere inside the function to not get confused about which object you are pointing to.
  • self in the setName function follows the lexical chain to find the variable self which points to the whole The c object allowing mutation of that object rather than the global object.
JavaScript: Understanding the Weird Parts (Part 6)

By Value vs. By Reference

  • Variables by value versus by reference.
  • by value - passing, referencing, or setting equal one value to another by copying the value
    • Two variables become the same by copying the value into two separate spots in memory.
  • by reference - two variables have the same value because they reference the same spot in memory
  • To summarize, by value means two variables pointing to two copies in different memory spots. By reference means two variables pointing to the same value in the same memory spot.
  • All objects interact by reference when setting them equal to each other or passing them to a function.
//by value (primitives)
var a = 3;
var b;
b = a;
  • b will be 3, a will be 3 but they are copies of each other sitting in different memory spots.
a = 2;
console.log(a); //a -> 2
console.log(b); //b -> 3
  • changing a does not affect b since they are in different memory spots.
//by reference (all objects, including functions)
var c = { greeting: 'hi'};
var d;
d = c;
  • Since these are objects, JavaScript points d to the same address as c.
c.greeting = 'hello'; //mutate
  • mutate - to change something
  • immuatable - cannot be changed
console.log(c); //-> {greeting: "hello"}
console.log(d); //-> {greeting: "hello"}

//by reference (even as parameters)
function changeGreeting(obj) {
    obj.greeting = 'Hola'; //mutate
}

changeGreeting(d);
console.log(c); //-> {greeting: "Hola"}
console.log(d); //-> {greeting: "Hola"}

//equals operator sets up new memory space (new address)
c = {greeting: 'howdy'};
console.log(c); //-> {greeting: "howdy"}
console.log(d); //-> {greeting: "Hola"}

All primitive types are by value and all objects are by reference.

JavaScript: Understanding the Weird Parts (Part 5)

JSON and Object Literals

  • JSON looks a lot like object literal syntax so a common mistake is to think they are the exact same thing.
    • JSON properties must be wrapped in quotes.
    • JSON is technically a subset of object literal syntax.
  • Anything that is valid JSON is also valid JavaScript object literal syntax but not all object literal syntax is valid JSON.
    • Like all dogs (JSON) are animals (objects) but not all animals are dogs.
JSON.stringify(objectLiteral);
  • Converts object to a JSON string, will wrap properties in quotes.
var jsonValue = JSON.parse('{"firstName": "Mary", 
                           "isAProgrammer": true}');
  • Converts JSON string to an object.

Functions are Objects

  • first class functions - everything you can do with other data types, you can do with functions; assign them to variables, pass them around, create them on the fly
  • A function is a special type of object and can have properties and methods attached to it.
  • A function's name is optional. It can be an anonymous function.
  • Think of the function code as a property attached to the function.
  • Functions can be moved around, copied, and given to other elements or areas of your code just like any other object or value.
function greet() {
    console.log('hi');
}
greet.language = 'english';
console.log(greet.language); //-> english
  • greet is the function's name. The text in the curly braces is the function's code.

Function Statements and Function Expressions

  • expression - a unit of code that results in a value; does not need to save to a variable
var a;
a = 3;
//-> 3

1 + 2;
//-> 3
  • Both of the above cases are expressions because they returned a value.
  • A statement does not return a value. Example: if statement.
function greet() { 
    console.log('hi');
} //function statement

var anonymousGreet = function() {
    console.log('hi');
} //function expression

anonymousGreet(); //-> hi
  • Function expressions are not hoisted, only the variable is hoisted.
JavaScript: Understanding the Weird Parts (Part 4)

Objects and Functions

  • In JS, objects and functions are related so much that they can be considered the same subject.

Objects and the Dot

  • Objects are collections of name/value pairs whose values can be other name/value pairs.
  • Objects can have primitive properties (boolean, number, etc.), object properties (child, etc.), and function methods.
  • The core object will have an address in the computer's memory and references to the different properties and methods
var person = new Object();
person["firstName"] = "Ella";
  • [ ] computed member access - access and set properties
console.log(person.firstName);
  • Preferred approach is to use the dot operator over the brackets because it is cleaner, clearer, and easier to debug
  • Use the dot operator unless accessing a property with a dynamic string

Objects and Object Literals

var person = {}; //create a new object by using 
                 //curly braces
var person = {
    firstName: 'Ella',
    lastName: 'Chiang',
    address: {
        street: '21 Street',
        city: 'Amazing Town'
        }
}

greet({
    firstName: 'Pickle', //create an object 
                         //on the fly while 
                         //calling a function
    lastName: 'Chiang'
});
  • This object can be used whereever a variable can be used.
Ella.address2 = {
    street: '888 2nd St'
};
  • Methodologies (dot notation and object literal) can also be mixed and matched

Faking Namespaces

  • namespace - a container for variables and functions to keep variables and functions with the same name separate
    • JavaScript does not have namespaces
var greet = 'Hello!';
var greet = 'Hola!';

console.log(greet); 
//-> Hola!, Hello! is overwritten

var english = {}; //create an object to
var spanish = {}; //use as a container

english.greet = 'Hello!';
spanish.greet = 'Hola!';

console.log(english); //-> Hello!
  • When an object is used as a container, there is no namespace collision (two things named the same) and Hello! is not overwritten.
english.greetings.greet = 'Hello!'; 
//produces Uncaught TypeError: 
//cannot set property 'greet' of undefined
  • dot is a left associative operator. Calling greetings on english yields undefined since english is empty.
  • Create english.greetings = {}; first, then use .greet.