JavaScript: Understanding the Weird Parts in 35ish minutes - Part 3/6

Credits
Prerequisite

Section 4 - Objects and Functions

Lesson 30- Objects and the Dot

In javascript, objects and functions are very much related

  • Object and the dot
  • The object can have primitive types connected to it's “property”
  • An object can have an object connected to it as a child “property”
  • An object can also contain functions “method” So an object can have properties and methods and these sit in the memory. The following example shows how to access these methods and properties.

Example 1

var person = new Object();
//person will get reference of the firstname in memory ie string property (primitive)
person[“firstname”] = “Tony”; 

//accessing the property 
var firstNameProperty = “firstname”;
console.log(person[firstNameProperty]);

//accessing property with dot operator
console.log(person.firstname);

//creating object inside object 
person.address =  new Object();

//using dot operator to add properties 
person.address.street = “111 Main st.”;
Lesson 31- Objects and Object Literals
var person = {}; //object literal same as new Object(); but this is much faster

var Tony = {
    firstname:’Tony’
};
function greet (person){
    console.log(“Hi ” + person.firstname);
}
greet(Tony);

//Create an object on the fly
greet({firstname:’Tony’,lastname:’Doe’});
Lesson 32- Framework Aside (Faking Namespaces)

#BIGWORD Namespace : A container for variables and functions, Typically to keep variables and functions with the same name separate.

var greet = “hello”;
var greet = “hola”;
console.log(greet);

//create an object, that would work as a container for our methods and properties
var english = {};
var spanish = {};
//now following greet will not collide with each other
english.greet = “hello”;
spanish.greet = “hola”;
console.log(english);
Lesson 33- JSON and Object Literals

JSON - Javascript Object Notation, It’s inspired by object literals

Example 1

//Object Literal
var objectLiteral = {
    firstName : “Mary”,
    isAProgrammer : true
}

In previous years data was sent over the internet in various formats and the format landed upon a while is XML. Problem was download time, Because it was using lots of bandwidth if you are dealing with lot of data so Object literal format was used to pass data in JSON string format. The only difference is properties are wrapped in quotes in JSON

//JSON - Subset of object literal syntax
{
    “firstName”: “Mary”,
    “isAProgrammer”: true
}
Lesson 34 - Functions are Objects

#BIGWORD First Class Function (FCF) - Everything you can do with other types you can do with functions. Assign them to variables, pass them around, create them on the fly.

  • Functions reside in memory
  • It’s a special type of object because it has all the features of the normal object as well as some special properties
  • We can attach primitive, object, functions to a function

Two special properties of functions are Name - optional,can be anonymous Code - The actual lines of code you have written is set in this property. The code you write is one of the property you are adding one to it. This property is invocable

Example 1

function greet(){
    console.log(“hi”);
}

//As we know functions are the objects, we can add a property to it
greet.language = “english”;
console.log(greet);
Output - we get only text the function we wrote

function greet(){
    console.log(“hi”);
}
console.log(greet.language); //english
Lesson 35- Function Statements and Function Expressions

#BIGWORD Expression - A unit of code that results in a value, It doesn’t have to save to a variable

//Function expression
a = 3
returns 3
//Function statement 
function greet(){
    console.log(“hi”);
}

Example 1 - As we know functions are objects in js. Here we are creating a function on the fly and setting it equal to a variable.

var anonymousGreet = function(){
    console.log(‘hi’);
}

// Here we still get function object. JS engine creates one and in this case, NAME property is anonymous but you can access it with a reference i.e variable name and CODE i.e invocable is console.log(“hi”);
// We can call this function using the following statement.
anonymousGreet();

Example 2

greet(); // OUTPUT : hi
function greet(){
    console.log(“hi”);
}

anonymousGreet(); // OUTPUT : Uncaught TypeError,  Undefined is not a function
// REASON : Because of function expressions are not hoisted.
var anonymousGreet = function(){
    console.log(“hi”);
}

Example 3

greet(); // OUTPUT : hi
function greet(){
    console.log(“hi”);
}

var anonymousGreet = function(){
    console.log(“hi”);
}

anonymousGreet(); // OUTPUT : hi

function log(a){
    console.log(a);
}

log(3); //creating a value on the fly -- OUTPUT : 3

log(“hello”); //creating a string on the fly -- OUTPUT : hello

log({
    greeting: ‘hi’
}); //creating an object on the fly -- OUTPUT : {greeting:”hi”}

log(function(){
    console.log(‘hi’);
});//creating anonymous function on the fly -- OUTPUT : function(){ console.log(‘hi’);}

Example 4 - Executing function created on the fly , Concept of first class functions where you can pass function around as a parameter, use them like variables called functional programming.

function log(a){
  a()
}

log(function(){
    console.log(“hi”);
});///OUTPUT : hi
Lesson 36- Conceptual Aside (By Value vs By Reference)

Pass by value

If a variable is primitive and it’s equated to other variables then a copy of the primitive value is created.

a = 3 // primitive value, It will sit in one address location in memory
b = a // copy of primitive value will be assigned to b, It will sit in other address location in memory

Pass by reference (objects)

If we set a variable equals to an object we get a location an address in memory that knows where that object lives and that’s how we reference it but when other b = a or we pass a to a function that new variable b instead of getting a new location in memory simply points to the location in memory a does, No new object is created, no copy of the object is created instead 2 names point to the same memory location This is called by reference

Example 1

//by value (primitives)
var a = 3;
var b;
b=a;
a = 2;
console.log(a); //2
console.log(b); //3 

New a will be 3 and b will be 3 sitting on different memory spots. That means we can change a and it will not affect b they are on their own.

//by reference (all objects (including functions))
var c = { greeting:’hi’};
var d;
d=c;
Now they are not copies of each other
c.greeting = ‘hello’;//mutate

#BIGWORD mutate - To change something “immutable can’t 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’}
Lesson 37- Objects, Functions and 'this'

//this

Example 1

console.log(this); //this is immediately available even at the global execution context, window object (global object)

Example 2

function a(){
    console.log(this); //window object
    //we can attach new variable to the window object
    this.newVariable = ‘hello’;
}
a();
console.log(newVariable);

Explanation - when you create a function the this keyword is still going to point the global object

Similarly,

Example 3

//var b gets a functional express by creating an anonymous function
var b = function a(){
    console.log(this);
} 
b(); //still window object

Example 4

var c = {
    name : ‘The c object’,
    log : function(){
        console.log(this); //the object in which the method is sitting inside of 
        }
}

c.log(); // Object {name : “The c object” ,log: function(){ console.log(this)}}

Example 5

var c = {
    name : ‘The c object’,
    log : function(){
        this.name = ‘Updated c object’; //mutate - change the object properties
        console.log(this); //the object in which the method is sitting inside of 
}
}

c.log(); // Object {name : “Updated c object” ,log: function(){ this.name = ‘Updated c object’;console.log(this)}}

BUG in js -

Example 6

var c = {
    name : ‘The c object’,
    log : function(){
        this.name = ‘Updated c object’; //mutate - change the object properties
        console.log(this); //the object in which the method is sitting inside of 
        var setname = function(newname){
            this.name = newname;
}
// didn’t work on c but added new property to window object
setname(‘Updated again!, The c object’); 
console.log(this);
}
}
c.log(); // Object {name : “Updated c object” ,log: function(){ this.name = ‘Updated c object’;console.log(this);var setname = function(newname){this.name = newname;} setname(‘Updated again!, The c object’);console.log(this);}}

A very common pattern can b used in this case to avoid errors in code because of “this”

var c = {
    name : ‘The c object’,
    log : function(){
        var self = this; //self will be pointing at the same location in memory as this
        self.name = ‘Updated c object’; //mutate - change the object properties
        console.log(self); //the object in which the method is sitting inside of 
        var setname = function(newname){
            self.name = newname; //js will look for self in scope chain
}
//will work now
setname(‘Updated again!, The c object’); 
console.log(self);
}
}
c.log(); //Object {name : “Updated again!, The c object” ,log: function(){ this.name = ‘Updated c object’;console.log(this);var setname = function(newname){this.name = newname;} setname(‘Updated again!, The c object’);console.log(this);}}
Lesson 38- Conceptual Aside (Arrays - Collections of Anything)

An array can be declared as

var arr = new Array();
var arr = [1,2,3];

JS arrays are dynamically typed.

var arr = [
    1,
    false,
    { 
    name : ‘Tony’,
    address : ‘22 Main st’
},
//it’s a function expression not statement inside array declaration
function(name){
    var greeting = “hello”;
    console.log(greeting + name);
},
“hello”
];

JS array can hold collections of anything. Invoking function in an array with-param in array

arr[3](arr[2].name);
Lesson 39 - 'arguments' and spread

#BIGWORD Arguments - The parameters you pass to a function, javascript gives you a keyword contains a list of all the values of all the parameters that you pass to a function.

Example 1

function greet(firstname, lastname, language){
    console.log(firstname);
    console.log(lastname);
    console.log(language);
}
//this function can be invoked without being any params passed to it
greet(); 
OUTPUT
undefined
undefined
undefined

greet(‘John’);
OUTPUT
John
undefined
undefined

greet(‘John’,’Doe’);
OUTPUT
John
Doe
undefined

greet(‘John’,’Doe’,’es’);
OUTPUT
John
Doe
es

Example 2

//setting up a default value
function greet(firstname, lastname, language){
     language = language || ’en’;
    console.log(firstname);
    console.log(lastname);
    console.log(language);
}
greet(‘John’,’Doe’);
OUTPUT
John
Doe
en

New Keyword #ARGUMENTS

Example 3

function greet(firstname, lastname, language){
    if(arguments.length === ‘0’){
    console.log(‘Missing parameters’);
    return;
}
     language = language || ’en’;
    console.log(firstname);
    console.log(lastname);
    console.log(language);
    console.log(arguments);
}
greet(‘John’,’Doe’);
OUTPUT
John
Doe
en
[‘John’,’Doe’] // containing all the values of params we have passed
Arguments - looks like an array, act like an array but not exactly the javascript array. It doesn’t have all the features of the javascript array

SPREAD

// using ...name (ES6)
// wrapping up all other arguments in ...other param
function greet(firstname, lastname, language, ...other){
    if(arguments.length === ‘0’){
    console.log(‘Missing parameters’);
    return;
}
     language = language || ’en’;
    console.log(firstname);
    console.log(lastname);
    console.log(language);
    console.log(arguments); 
}
greet(‘John’,’Doe’,’es’,’111 main st’,’new york’);
Lesson 40- Framework Aside (Function Overloading)

Function Overloading means we can have a function of the same name with the different number of params. This thing is not available in js because functions are objects.

function greet ( firstname,lastname,language ) {
    language = language || ‘en’; //default param
    if(language == ‘en’){
        console.log(“Hello ” + firstname + “ ” + lastname);
} 
    if(language == ‘es’){
        console.log(“Hola ” + firstname + “ ” + lastname);
} 
}
greet(‘John’,’Doe’,’en’); //Hello John Doe
greet(‘John’,’Doe’,’es’); //Hola John Doe
Lesson 41- Conceptual Aside (Syntax Parsers)

Code doesn’t directly run on a computer there is an intermediate program b/w code and the computer that translates your code into something that a computer could understand. The js engine for eg does this and it has different aspects to it one of being a syntax parser which reads the code and determines what it does

Lesson 42- Dangerous Aside (Automatic Semicolon Insertion)

Semicolons are optional in core-js The syntax parser in the js engine injects automatically the semicolon at the end of the required syntax.

Example 1

function getPerson(){
    return 
    {
        firstname:’Tony’
    }
}

console.log(getPerson()); //gives error as it adds semicolon after return 
Following will work 
function getPerson(){
    return {
        firstname:’Tony’
    }
}
Lesson 43- Framework Aside (Whitespace)

#BIGWORD Whitespace - Invisible characters that create literal ‘space’ in your written code, Carriage returns, tabs, spaces

Example 1

var 
    //first name of the person
    firstname,

    //last name of the person
    lastname,

    //the language
    //can be ‘en’ or ‘es’
    language;

var person = {
    //the  first name
    firstname: ‘John’,

    //the last name 
    //(always required)
    lastname: ‘Doe’
}
console.log(person);
Lesson 44- Immediately Invoked Functions Expressions (IIFEs)

Example 1

//function statement
function greet(name){
    console.log(name)
}
//invoke it with following line
geet();

//function expression , creating function object on the fly
var greeFunc = function(name){
    console.log(name);
}
//invoke it with following line
greetFunc();

//IIFE - Immediately invoked functions expression
Example 1
var greeting = function(name){
    return name;
}(‘John’);
console.log(greeting); // OUTPUT - John

Example 2

3; //this is a valid js expression, it will not throw error message

Example 3

“I’m a string //this is also a valid js expression, it will not throw an error message

Example 4

{
name : ‘john’    
}

Example 5

//This will throw an error - unexpected token parenthesis 
//REASON - Syntax parser expects it to be function statement
function (name){
    return (name);
}

Example 6

//This will not throw any error, everything inside parenthesis is assumed as an expression so this will be treated as a function expression. Here you are creating function object on the fly
(function (name){
    return (name);
});

Example 7

//A classic example of IIFE
//Writing a function expression and executing it on the fly
(function (name){
    console.log(“Inside IIFE” + name);
}(‘John’))
//OUTPUT : Inside IIFE John
Lesson 45- Framework Aside (IIFEs and safe Code)

Example 1

//IIFE
(function (name){
    var greeting = “Inside IIFE ”;
    console.log(greeting + name);
}(‘John’))
//OUTPUT: Inside IIFE John

Explanation - Creating function on the fly and executing it, When the code is executed It creates a global execution context and nothing is in it as we don’t have any global variables or function statements to be hoisted. Then it hits immediately invoked function expression. Then it creates that function object in memory. Then a new execution context is created for that anonymous function then code is run line by line in that function. All variables will be declared in that new execution context

What is a closure? A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables.

The inner function has access not only to the outer function’s variables but also to the outer function’s parameters. Note that the inner function cannot call the outer function’s arguments to object, however, even though it can call the outer function’s parameters directly.

Closure from other resources:

Lesson 46- Understanding Closures

Example 1

function greet(whattosay){
    return  function(name){
    console.log(whattosay + ‘ ’ + name);
}
}

//We are invoking a function that returns a function so that we can invoke the returned function
greet(‘Hi’)(‘Tony’); // OUTPUT : Hi Tony

Example 2

function greet(whattosay){
    return  function(name){
    console.log(whattosay + ‘ ’ + name);
}
}

//sayHi will be the function which was returned by calling greet
var sayHi = greet(‘Hi’); 
sayHi(‘Tony’) //OUTPUT : Hi Tony;

Now how does sayHi function knows the whattosay variable?

Explanation - When this code starts we have global execution context then we invokes greet function and created new execution context of greet() and that variable which was passed to it whattosay is sitting in its variable environment, it returns a new function object and creates a function on the fly and returns it. After that return the greet execution context is popped off the stack.

Under normal circumstances, js engine clears out the memory space using garbage collection but at the moment that execution context finishes that memory space is still there for (whattosay) variable, It’s still hanging around now we move on the global execution context then we invoke the function sayHi(). It’s an anonymous function and that creates a new execution context and we have name variable to it so it ends up in memory.

When we hit a line console.log(whattosay + ‘ ’ + name); when this code is invoked js engine sees whattosay variable it goes up the scope chain, it goes to outer lexical environment, in this case, to look for the variable since it couldn’t find it inside the function itself. sayHi has reference to the variable whattosay which is available in the memory space of its outer environment. This phenomenon is called closure.

Closures are simply the feature of the javascript programming language. We don’t have to worry if it’s out environment is still running. Js engine handles the reference to variables in the lexical out environment.

The js engine creates the closure we are just taking advantage of it.

Lesson 47- Understanding Closures (Part 2)

Example 1

function buildFunctions(){
    var arr = [];
    for(var i =0 ;i <3;i++){
        //creating the function, not executing
        arr.push(
     function(){
        console.log(i);
     })
    }
    return arr;
}

var fs = buildFunctions();
//executing the functions 
fs[0]();//3
fs[1]();//3
fs[2]();//3

Why? Global execution context is always there buildFunctions(), fs When buildFunctions get invoked we get arr [f0,f1,f2] and i 3 After this buildFunctions execution context is popped off the stack fs[0]() execution context is created there is no variable i inside the scope so it goes up the scope chain if finds i = 3 hangging around then fs[1]() and then fs[2]() also has same outer environment reference

Overcoming this problem

 function buildFunctions2(){
    var arr = [];
    for(var i =0 ;i <3;i++){
        //the only way to get execution context of i in function is by executing the function
        //creating the function, not executing
        arr.push(
            //IIFE - immediately invoke function expression
    (function(j){
        console.log(j);
        }(i))
       )
     }
   return arr;
}

function buildFunctions2(){
    var arr = [];
    for(var i =0 ;i <3;i++){
            arr.push(((j) => {
                return () => console.log(j)
            })(i))

    }
    return arr;
}


var fs2 = buildFunctions2();
//executing the functions 
fs2[0]();//1
fs2[1]();//2
fs2[2]();//3    
Lesson 48- Framework Aside (Function Factories)

The factory is a function which returns and makes other things for app

Example 1

function makeGreeting(language){
    return function(firstname, lastname){
        if(language==’en’){
            console.log(“Hello” + firstname + lastname);
                 }
        if(language==’es’){
            console.log(“Hola” + firstname + lastname);
                 }
               }
}

var greetEnglish = makeGreeting(‘en’);
var greetSpanish = makeGreeting(‘es’);
greetEnglish(‘John’,’Doe’);
greetSpanish(‘John’,’Doe’);
Lesson 49- Closures and Callbacks

Example 1

function sayHiLater(){
    var greeting = ‘Hi!’;
    setTimeout(function(){
        console.log(greeting);
},3000)
}
sayHiLater(); //It will wait 3000 milliseconds and then prints hi

#BIGWORD - Callback function - A function you give to another function, to be run when the other function is finished. So the function you call (ie invoke) ‘call back’ by calling the function you gave it when it finishes.

Example 2 - Callback function

function tellMeWhenDone(callback){
    var a = 1000;
    var b = 2000;
    callback(); //the callback, it runs the function i give it.
}

tellMeWhenDone(function(){
    alert(‘I am done’);
});
Lesson 50 - call(), apply(), and bind() (Borrowing,Curring)

Example 1

var person = {
    firstname: ‘John’,
    lastname: ‘Doe’,
    getFullName: function(){
        var fullname = this.firstname + this.lastname;
        return fullname;
        }
}

var logName = function(lang1,lang2){
    console.log(‘logged’ + this.getFullName();
}

logName() // this will fail.
var logPersonName = logName.bind(person);
logPersonName();

Example 2
var person = {
    firstname: ‘John’,
    lastname: ‘Doe’,
    getFullName: function(){
        var fullname = this.firstname + this.lastname;
        return fullname;
        }
}

var logName = function(lang1,lang2){
    console.log(‘logged’ + this.getFullName();
}.bind(person);

logName() // this will work.

#.bind creates copy of the function we are calling it on

Example 3 - Call is used to call the function

var person = {
    firstname: ‘John’,
    lastname: ‘Doe’,
    getFullName: function(){
        var fullname = this.firstname + this.lastname;
        return fullname;
        }
}

var logName = function(lang1,lang2){
    console.log(‘logged’ + this.getFullName();
}

logName() // this will fail.
// calling with reference object and params 
logName.call(person,’en’.’es’);

Example 4 - apply - does the same exact thing as a call but it takes an array as a parameter

logName.appy(person,[’en’.’es’]);

Example 5 - Creating it on the fly and calling it using apply

(function(lang1,lang2){
    console.log(‘logged’ + this.getFullName();
}).apply(person,[‘en’,’es’]);

We can use call, apply in function borrowing in objects

function currying - binding (creating new copy of the function)
function multipy(a,b){
    return a*b;
}
//bind with params, bind is not executing the function 
//giving params sets permanent values with bind when copy of function is made
//var a = 2 in following function
var multipyByTwo = multipy.bind(this,2)
multipyByTwo(3); // OUTPUT - 6

#BIGWORD Function Currying - Creating a copy of the function with some preset parameters - Very useful in mathematical situations

Lesson 51- Functional Programming

First Class Functions - Functions that behaves like objects, passed as parameters, return them from functions

Example 1 - Creating new array out of given array

var arr1 = [1,2,3];
console.log(arr1);

var arr2 = [];
for(var i=0;i<arr1.length;i++){
    arr2.push(arr1[i]*2);
}

console.log(arr2);

Example 2 - Creating new array out of given array using functional programming

function mapForEach(arr, fn){
    var newArr = [];
    for(var i=0; i<arr.length; i++){
        newArr.push(fn(arr[i]);
    }
    return newArr;
}

var arr1=[1,2,3];

//multiply by 2 and copying values in array
var arr2 = mapForEach(arr1,function(item){
    return item*2;
});

//OUTPUT 

arr2 = [2,4,6];
//check if item is greater than 2 and creating new array of boolean items

var arr3 = mapForEach(arr1,function(item){
    return item>2;
});

//OUTPUT
arr3 = [false, false, true];

Example 3

var checkPastLimit = function(limiter, item){
    return limiter < item;
}

//created copy of checkPastLimit on the fly and passing limiter = 1
var arr4 = mapForEach(arr1, checkPastLimit.bind(this, 1));
console.log(arr4);

//OUTPUT
arr4 = [false,true,true];

//passing only limit to a function and returning checkPastLimit
var checkPastLimitSimplified = function (limiter){
    return function(limter, item){
        return limiter < item;
}.bind(this,limiter); //using bind to set first param pre-set
};

var arr5 = mapForEach(arr1,checkPastLimitSimplified(1));

//OUTPUT
arr5 = [false,true,true];
Lesson 52- Functional Programming (Part 2)
//Refer - underscorejs.org , lodash.com

Subscribe

If you want a gist of the actual document, subscribe to the newsletter.


Bookmark

Unlike life, keyboards do have shortcuts, press COMMAND+D to make this an easily accessible resource by bookmarking it.

Comments (0)