Variables and Some Built-In Functions

CSCI-UA.0480-008

Some Definitions

We learned how to produce values from using operators on other values. We created expressions!.

  • expression - a fragment of code that produces a value
    • not a statement by itself
    • every literal value is an expression - 27, "YES!"
  • statement - a full instruction/action for the computer
    • in JavaScript most statements end in a semicolon (;)
    • the simplest statement is an expression with a semicolon at the end - 27;, "YES!";
  • program - a sequence of statements that specify to a computer actions to perform
  • function - a named sequence of code that can be called by name
  • built-in function - a function available in the global namespace that is part of the core language

Expressions and Statements Examples


// Expression (no semicolon), evaluates to 6
1 + 5

// Statement, contains an expression
1 + 5;

// Statement, contains multiple expressions
parseInt("4" + "2");

// Even these are statements:
1;
"hi";
  • Note that loops and if statements are also examples of (of course) statements, but they don't end in a semicolon.
  • Any statements that end with a block (curly braces) are not terminated with a semicolon.

A Quick Note on Functions

If you declare a function using this (function declaration) syntax:


// function declaration, a single statement
function f() {
    // do stuff
}

… you have a single statement (note, no semicolon at the end).

However, any statement that:

  • involves functions
  • but doesn't start with the actual keyword, function
  • will have a function expression (that is, an expression that evaluates to a function) in it:



const foo = function bar(bax) {}; // <-- function expression
const qux = function(corge) {}; // <-- function expression

Soooo… most statements end with a semicolon.

Automatic Semicolon Insertion

JavaScript has a feature that automatically inserts semicolons at the end of statements (Automatic Semicolon Insertion / ASI)

  • semicolons are actually optional and are placed at the end of statements for you! 👍
  • but there are some corner cases where ASI doesn't work as expected 👎 (below, ASI inserts a ; immediately after return!)
    
    return
    {
      name: 'John'
    }
    
  • as with other classic divisive issues such as tabs vs spaces, there are two very opinionated camps on this:
    1. always explicitly include semicolons in your code because of the instances where ASI doesn't work
    2. never use semicolons; ASI corner cases are rare and finite
  • just pick one and be consistent (I try to use #1)

Functions

What's a function?

  • a function is a named sequence of statements that perform some useful action.
  • it can take inputs, and it can return values, but it doesn't have to do either
  • to call (or execute) a function, just call it by name, with parentheses after (with an optional list of commas separated inputs within the parentheses)
  • the values passed to a function are called arguments
  • for example: isNaN(12) is a function call

To call a function, use its name followed by parentheses.

Built-In Functions

JavaScript comes with a bunch of built in functions (and objects) that are available globally. Here are a couple:

  • parseInt(string, radix) - returns an integer based on the string and radix
    • always specify radix
    • parseInt("100", 2)
    • parseInt("100", 10)
  • console.log(obj1 [,obj2 …, objN]) - outputs a message (the string representation of obj) to the console (more on objects and methods later)
    • console.log("hi")
    • console.log("hi", "hello")

Variables

Variables are symbolic names for values; you can use a variable's name wherever you want to use that value.

To create a variable, start with one of the following keywords:

  • const or let (ES6) … or var
  • followed by a variable name
  • optionally, assign a value to the variable by using = and a value or expression
  • of course, you can add a semicolon (or not)
  • notice that type does not have to be specified!



const s = 'hello';
let i = 21 * 2;
console.log(s);
console.log(++i);

What's in a Name?

We can create identifiers, or variable names, based on these rules:

  • start with a letter, underscore (_), or dollar ($)
  • following characters can be any of above, and/or digits (0-9)
  • variable names are case sensitive
  • cannot be a reserved word


Speaking of reserved words….

Don't Use Reserved Words as Variable Names


abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface

let long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with

Block Scope w/ const or let (ES6)

Wait, so it looks like there are three ways to declare variables. What's the difference? Let's look at const and let first

  • the scope of variables declared with const and let is the block that they're contained in
  • a block is simply the area between opening and closing curly braces



{
   const s = 'in'; // just need two curly braces to make a block!
}

for(let i = 0; i < 10; i++) {
   const s = 'also in'; // for loop body is a block!
}

function f() {
   const s = 'in too'; // function body is a block!
}

Block Scope Continued

Accessing a variable when it's out of scope produces a run-time error (specifically a ReferenceError)!


console.log('out there');
{
   const s = 'in here'; 
}
console.log(s);

(heeeey… sort of just like Java)

Variables in an outer scope are visible from an inner scope:


{
    const first = 'out there';
    {
        const full = `${first} in here`;
        console.log(full);
    }
}

Temporal Dead Zone

This may seem obvious, but accessing a variable declared by let or const before it's declared will give a syntax error.

  • for example:
    
    console.log(s);
    let s = 'after!';
    // ReferenceError! s was used before it was declared
    
  • the "area"/time between the start of a scope and when a variable is actually declared is called the Temporal Dead Zone (really, it's true)
  • why does this matter? var does not behave this way!? (we'll see this in the slides on hoisting)

const vs let

OK… so what's the difference between const and let then?

  • a variable declared with const can't be assigned a different value after it had been declared
  • const reassignment will result in a run-time error (TypeError)
    
    const dontChangeMe = "I told you so";
    dontChangeMe = "why not?";
    
  • note, however, that this does not mean the variable is immutable
  • in fact, if a const declared variable is mutable, it can still be changed without error
    
    const arr = [1, 2, 3];
    arr[0] = 'wat? this is ok!?';
    console.log(arr);
    
  • on the other hand, let declared variables can be reassigned
    
    let i = 0;
    i = i + 2;
    console.log(i);
    

const vs let Continued

Again, a value cannot be assigned to a const declared variable after it's been declared. This implies that…

  • from mdn: "An initializer for a constant is required; that is, you must specify its value in the same statement in which it's declared"
  • or, simply put, you must assign a value immediately when declaring a variable with const
  • otherwise, you'll get a syntax error:
    
    const foo;
    foo = 'bar'
    // SyntaxError: Missing initializer in const declaration
    

Default Initial Value

When you declare a variable without assigning a value to it, it will be initialized to undefined (this is really only valid for let and var, of course). →

For example, the output of this…


let a;
console.log(a);

is


undefined

Redeclaring Variables with let and const

If a variable has already been declared (with let, const, or var)… →

  • redeclaring a variable with the same identifier (name) with let and const will result in a SyntaxError
  • for example:
    
    let i = 0;
    let i = 1;
    

A Note About Loops

let and const behavior in loops: →

  • if the loop variable is incremented/decremented, it must be declared as 'let':
    
    for(let i = 0; i < 10; i++) { console.log(i); }    
    
  • repeatedly creating a variable with let or const in a loop body does not count as redeclaration (works fine; it's another scope!)
    
    for(let i = 0; i < 10; i++) { 
      const j = i * 2;
      console.log(j);
    }    
    

let / const Examples #1

What's the output of this code? No output and error are possible


if(true) {
    let name = 'Joe';
} else {
    let name = 'Not Joe';
}
console.log(name);

ReferenceError: name is not defined
// name is not in scope (name is declared within the if statement)

let / const Examples #2

What's the output of this code? No output and error are possible


let name;
if(true) {
    name = 'Joe';
    {
        let full = name + ' Versoza';
        console.log(full);
    }
} else {
    name = 'Not Joe';
}
console.log(full);

Joe Versoza
ReferenceError: full is not defined
// name is in scope, so full is Joe Versoza
// but full is not in scope in last line

let / const Examples #3

What's the output of this code? No output and error are possible


for(const i = 0; i < 4; i++) {
    console.log(i);
}

TypeError
// assignment to constant (i is incremented)

var

var creates a variable in function level scope, regardless of where it appears in the function

What's the output of the following code?


function foo() {
    if(true) {
        var bar = 'baz';
    }     
    console.log(bar);
}
foo();

baz
  • even though bar is in a block, its scope is the entire function!
  • var was the only keyword for declaring variables in ES5
  • behavior may seem unexpected if coming from a language with block scope

Redeclaring Variables with var

If a variable has already been declared var… →

  • redeclaring a variable with var again is ok!
  • for example:
    
    // no syntax error
    var a = 'bar';
    var a = 'baz';
    
  • redeclaring with var but not assigning a value will have no effect on the original value:
    
    // no syntax error
    var a = 'bar';
    var a;
    // a is still 'bar'
    

Always use const or let (or var, I guess) when declaring variable names!

If you don't declare variables with these keywords:

  • you get global variables!
  • This is particularly important when dealing with variable declarations in functions

(Not) Declaring a Variable

What happens if you don't use const, let or var?

  • … you might end up modifying a variable in an outer scope!
  • or inadvertently creating a global variable ಠ_ಠ
    
    function foo() {
      wat = 'uh oh!';
    }
    foo();
    console.log(wat);
    


What happens if you don't declare a variable at all?

  • if you use a variable/identifier without ever declaring it (with or without const, let, or var)
  • you get a runtime error: ReferenceError: variable is not defined

And Speaking of a Look of Disapproval

(Variable Names)

What are the rules for a valid identifier (variable name) again?

  • start with a letter, underscore ( _ ), or dollar ( $ )
  • following characters can be any of above, and/or digits (0-9)
  • can't use reserved words / keywords

Don't Do This, But…

BTW, Unicode characters are allowed in variable names!!!


const ಠ_ಠ = "disapproval";
console.log(ಠ_ಠ);
// totally works (O_o !?)

Thanks Stackoverflow! Also, here's more about that look.

Oh, and this is a site that let's you check if a variable name is valid or not.

Another Note on Variables

Because JavaScript is dynamically typed… variable reassignment (for let and var, even of different types, is ok


let x = 25;
x = "foo";

Lastly, a quick aside…

Ok… Soooo, When to Use What

const vs let vs var… There are a few ways to approach this (what do you think):

  1. use the appropriate keyword to express your intent … for example, if you know that you want a variable available throughout the function - use var, block level scoping - use const or let
  2. never use var
    1. default to using const, and only use let when you know you need reassignment (like incrementing a loop variable)
    2. default to using let and use const to signify a constant


My preference is default to using const (#2, #1), mainly because it seems to be way the community is moving (preventing reassignment may reduce side effects / bugs).

Definition Time

(What time is it?)

From Speaking JavaScript:

  • the environment is the collection of variables and their values that exist at a given time
  • when a program starts up, this environment is not empty
  • it always contains variables that are part of the language standard
  • for example:
    • the console object is an available variable from the start of your program!
    • same with built-in functions!