JavaScript Up & Going

Parsa Hejabi

Statements

a = b * 2

Statements

a = b * 2
  • 2 is a "literal value expression"
  • b is a "variable expression"
  • b * 2 is a "arithmatic expression"
  • a = b * 2 is a "assignment expression"

Expressions

b * 2;

“A general expression that stands alone is also called an expression statement”

Expressions

alert ( a );

call expression statement

“It’s typically asserted that JavaScript is interpreted, because your JavaScript source code is processed each time it’s run. ”

 

“But that’s not entirely accurate. The JavaScript engine actually compiles the program on the fly and then immediately runs the compiled code.”

Hands on!

console.log(...);

“how we print text (aka output to the user) in the developer console.”

alert(...);

“Another way of creating output that you can see”

“age = prompt( "Please tell me your age:" );

console.log( age );”

“way to get input”

👎🏻

0
 Advanced issue found

Operators

  • Equality:
    • == (loose-equals)
    • === (strict-equals)
    • != (loose not-equals)
    • !== (strict not-equals)

Values & Types

  • number
  • string
    • literals in '...' or "..."
  • boolean
  • null and undefined
  • object
  • symbol (new to ES6)

Conversion or "Coersion"

var a = "42";
var b = Number( a );

console.log( a );   // "42"
console.log( b );   // 42

Explicit coercion

Conversion or "Coersion"

var a = "99.99" == 99.99;

console.log(a); //true

Implicit coercion

"typeof"

var a;
typeof a;               // "undefined"

a = "hello world";
typeof a;               // "string"

a = 42;
typeof a;               // "number"

a = true;
typeof a;               // "boolean"

a = null;
typeof a;               // "object"--weird, bug

a = undefined;
typeof a;               // "undefined"

a = { b: "c" };
typeof a;               // "object”

Comments

// This is a single-line comment

/* But this is
       a multiline
             comment.
                      */

Dynamic typing of JS

  • “In some programming languages, you declare a variable (container) to hold a specific type of value, such as number or string. Static typing, otherwise known as type enforcement, is typically cited as a benefit for program correctness by preventing unintended value conversions.”
  • “Other languages emphasize types for values instead of variables. Weak typing, otherwise known as dynamic typing, allows a variable to hold any type of value at any time. It’s typically cited as a benefit for program flexibility”

Dynamic typing of JS

var amount = 99.99;

amount = amount * 2;

console.log( amount );      // 199.98

// convert `amount` to a string, and
// add "$" on the beginning
amount = "$" + String( amount );

console.log( amount );      // "$199.98”

Constants

var TAX_RATE = 0.08;    // 8% sales tax

var amount = 99.99;

amount = amount * 2;

amount = amount + (amount * TAX_RATE);

console.log( amount );              // 215.9784
console.log( amount.toFixed( 2 ) ); // "215.98”
// as of ES6:
const TAX_RATE = 0.08;

var amount = 99.99;

Older version of JS

ES6 version of JS

Let's get more
SERIOUS

Blocks

var amount = 99.99;

// a general block
{
    amount = amount * 2;
    console.log( amount );  // 199.98
}

“In JavaScript, a block is defined by wrapping one or more statements inside a curly-brace pair { .. }”

Blocks

var amount = 99.99;

// is amount big enough?
if (amount > 10) {          // <-- block attached to `if`
    amount = amount * 2;
    console.log( amount );  // 199.98
}

Conditionals

const ACCESSORY_PRICE = 9.99;

var bank_balance = 302.13;
var amount = 99.99;

amount = amount * 2;

// can we afford the extra purchase?
if ( amount < bank_balance ) {
    console.log( "I'll take the accessory!" );
    amount = amount + ACCESSORY_PRICE;
}
// otherwise:
else {
    console.log( "No, thanks." );
}

Loops

while (numOfCustomers > 0) {
    console.log( "How may I help you?" );

    // help the customer...

    numOfCustomers = numOfCustomers - 1;
}

// versus:

do {
    console.log( "How may I help you?" );

    // help the customer...

    numOfCustomers = numOfCustomers - 1;
} while (numOfCustomers > 0);

// for:

for (var i = 0; i <= 9; i = i + 1) {
    console.log( i );
}
// 0 1 2 3 4 5 6 7 8 9

Scopes!!!

  • technically: lexical scope
  • “a collection of variables as well as the rules for how those variables are accessed by name.”

  • “In JavaScript, each function gets its own scope.”

  • “A variable name has to be unique within the same scope there can’t be two different a variables sitting right next to each other.”

Scopes!!!

function one() {
    // this `a` only belongs to the `one()` function
    var a = 1;
    console.log( a );
}

function two() {
    // this `a` only belongs to the `two()` function
    var a = 2;
    console.log( a );
}

one();      // 1
two();      // 2

Scopes!!!

function outer() {
    var a = 1;

    function inner() {
        var b = 2;

        // we can access both `a` and `b` here
        console.log( a + b );   // 3
    }

    inner();

    // we can only access `a` here
    console.log( a );           // 1
}

outer();

“Lexical scope rules say that code in one scope can access variables of either that scope or any scope outside of it.”

Scopes!!!

const TAX_RATE = 0.08;

function calculateFinalPurchaseAmount(amt) {
    // calculate the new amount with the tax
    amt = amt + (amt * TAX_RATE);

    // return the new amount
    return amt;
}

“Lexical scope rules say that code in one scope can access variables of either that scope or any scope outside of it.”

Objects

var obj = {
    a: "hello world",
    b: 42,
    c: true
};

obj.a;      // "hello world"
obj.b;      // 42
obj.c;      // true

obj["a"];   // "hello world"
obj["b"];   // 42
obj["c"];   // true

Objects

var obj = {
    a: "hello world",
    b: 42
};

var b = "a";

obj[b];         // "hello world"
obj["b"];       // 42

Arrays

var arr = [
    "hello world",
    42,
    true
];

arr[0];         // "hello world"
arr[1];         // 42
arr[2];         // true
arr.length;     // 3

typeof arr;     // "object”

An array is an object. so they have some properties like length

Functions

function foo() {
    return 42;
}

foo.bar = "hello world";

typeof foo;         // "function"
typeof foo();       // "number"
typeof foo.bar;     // "string"

object subtype.

Built-In type methods

var a = "hello world";
var b = 3.14159;

a.length;               // 11
a.toUpperCase();        // "HELLO WORLD"
b.toFixed(4);           // "3.1416”
  • String object wrapper
  • defines toUpperCase() method on its prototype
  • JS automataically "boxes" the value to its object wrapper

Built-In type methods

  • number can be wrapped by Number object
  • boolean can be wrapped by Boolean object

Is "Coercion" evil? 😈

var a = "42";
var b = a * 1;  // "42" implicitly coerced to 42 here

a;              // "42"
b;              // 42--the number!

/*----------------------------------------*/
console.log("ba" + NaN + "a"); // "BaNaNa"

Is "Coercion" evil? 😈
Truthy & Falsy

// List of "falsy" values in JS:
"" // (empty string)
0, -0, NaN // (invalid number)
null, undefined
false

Is "Coercion" evil? 😈
Truthy & Falsy

"hello"
42
true
[ ], [ 1, "2", 3 ] (arrays)
{ }, { a: 42 } (obejcts)
function foo() { .. } (functions)

"Truthy" values are any value that is not on "falsy" list

Equality

  • == checks for value equality with coercion allowed
  • === checks for value equality without allowing coercion
var a = "42";
var b = 42;

a == b;         // true
a === b;        // false

Equality

  • If either value (or side) in a comparison could be the true or false use ===
  • If either value (or side) in a comparison could be of these specific values (0, "", or [ ] --empty array), use ===
  • In ALL other cases you're safe to use ==
  • Simply you can use === all the time.

Equality

Take special note of the == and === comparison rules if you're comparing two non-primitive values, like objects (including functions and arrays)

0
 Advanced issue found
 
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";

a == c;     // true
b == c;     // true
a == b;     // false

Inequality

var a = 41;
var b = "42";
var c = "43";

a < b;      // true
b < c;      // true
  • “JavaScript string values can also be compared for inequality, using typical alphabetic rules ("bar" < "foo").”
  • If both values are strings, lexicographically
  • If one or both is not a string, both values "coerced" to numbers

Inequality

var a = 42;
var b = "foo";

a < b;      // false
a > b;      // false
a == b;     // false

How can all of those three comparisons be false?!!!

🤔

Inequality

var a = 42;
var b = "foo";

a < b;      // false
a > b;      // false
a == b;     // false

How can all of those three comparisons be false?!!!

For < and >: NaN! (invalid number value)

For ==: 42 == NaN is false!

Variables

  • In JS variable names (including function names) must be valid identifiers.
  • An identifier must start with a-z, A-Z, $ or _. It can then contain any of those characters plus the numerals 0-9.
  • "reserved words" cannot be used as variables, but are OK as property names. (for, in, if, etc) as well as null, true and false.

Function scopes and "Hoisting"

var a = 2;

foo();                  // works because `foo()`
                        // declaration is "hoisted"

function foo() {
    a = 3;

    console.log( a );   // 3

    var a;              // declaration is "hoisted"
                        // to the top of `foo()`
}

console.log( a );   // 2

Nested scopes

function foo() {
    var a = 1;

    function bar() {
        var b = 2;

        function baz() {
            var c = 3;

            console.log( a, b, c ); // 1 2 3
        }

        baz();
        console.log( a, b );        // 1 2
    }

    bar();
    console.log( a );               // 1
}

foo();
function foo() {
    a = 1;  // `a` not formally declared
}

foo();
a;          // 1--oops, auto global variable :(

Bad practice!

Automatically created variable on the top-level global scope!
function foo() {
    var a = 1;

    if (a >= 1) {
        let b = 2;

        while (b < 5) {
            let c = b * 2;
            b++;

            console.log( a + c );
        }
    }
}

foo();
// 5 7 9

let keyword in ES6

“ES6 lets you declare variables to belong to individual blocks (pairs of { .. }), using the let keyword.”

Functions as Values 

var foo = function() {
  console.log("1");
};

var x = function bar() {
  console.log("2");
};


foo(); // 1
bar(); // Uncaught ReferenceError: bar is not defined
x(); //2

Immediately Invoked Function Expressions (IIFEs)

(function IIFE(){
 console.log( "Hello!" );
})();
// "Hello!"

Immediately Invoked Function Expressions (IIFEs)

function foo() { .. }
// `foo` function reference expression,
// then `()` executes it
foo();
// `IIFE` function expression,
// then `()` executes it
(function IIFE(){ .. })();

Immediately Invoked Function Expressions (IIFEs)

(function IIFE(a, b){
 console.log( a + b );
})(12, 15); 
// 27

Closure

function makeAdder(x) {
 // parameter `x` is an inner variable
 // inner function `add()` uses `x`, so
 // it has a "closure" over it
  function add(y) {
    return y + x;
  };
  return add;
};


// `plusOne` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusOne = makeAdder( 1 );

// `plusTen` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusTen = makeAdder( 10 );

plusOne( 3 ); // 4 <-- 1 + 3
plusOne( 41 ); // 42 <-- 1 + 41
plusTen( 13 ); // 23 <-- 10 + 13

Modules

function number(value) {
  var x = value;
  function increment() {
    x++;
  };
  function decrement() {
    x--;
  };
  function getValue() {
    return x;
  };
 
  return {
    getValue: getValue,
    increment: increment,
    decrement: decrement
  };
};

var a = number(10);
a.getValue(); // 10
a.increment();
a.getValue(); // 11

this?! 🤔

identifier

function foo() {
  console.log(this.bar);
}

var bar = "global";

var obj1 = { bar: "obj1", foo: foo };

var obj2 = { bar: "obj2" };


// --------

foo (); // "global"
obj1 . foo (); // "obj1"
foo . call ( obj2 ); // "obj2"
new foo (); // undefined
  1. foo() ends up setting this to the global object in non-strict mode (in strict mode, this would be undefined and you’d get an error in accessing the bar property) so "global" is the value found for this.bar.
  2. obj1.foo() sets this to the obj1 object.
  3. foo.call(obj2) sets this to the obj2 object.
    
  4. new foo() sets this to a brand new empty object.

Old and New

(Specially the arrays)

Thank you! 👋

Feel free to contact me on my website!

Made with Slides.com