WDIM387 Week 2

JavaScript functions


Instructor: Dan Muzyka

danmuzyka.ai@gmail.com

Operators (Review from last week)





Net Tuts Video

Conditional Statements


if (porridge === 'too hot') {
  spitOut();
}

else if (porridge === 'too cold') { pourDownDrain(); }
// Else porridge is 'just right' else { devour(); }

Conditional Statements


 switch (porridge) {
case 'too hot':
spitOut();
break;

case 'too cold':
pourDownDrain();
break;

// Otherwise, assume 'just right'
default:
devour();
break;
}

Conditional Statements


switch (porridge) {
// If too hot or too cold, both spit out and pour down drain.
case 'too hot':
case 'too cold':
spitOut();
pourDownDrain();
break;

// Otherwise, assume 'just right'
default:
devour();
break;
}

Loops


var bowlsOfPorridge = [hotBowl, coldBowl, justRightBowl];

for (var i = 0; i < bowlsOfPorridge.length; i++) {
taste(bowlsOfPorridge[i]);
}

Loops


var bowlsOfPorridge = [hotBowl, coldBowl, justRightBowl];

for (var i = 0, numBowls = bowlsOfPorridge.length; i < numBowls; i++) {
taste(bowlsOfPorridge[i]);
}

Loops


var bowlsOfPorridge = [hotBowl, coldBowl, justRightBowl];

for (var i = bowlsOfPorridge.length; i--;) {
taste(bowlsOfPorridge[i]);
}


What is happening here? What are the benefits? What are the drawbacks?

Loops


var bowlsOfPorridge = [hotBowl, coldBowl, justRightBowl],
i = bowlsOfPorridge.length - 1;

do {
taste(bowlsOfPorridge[i]);
i--;
} while (i >= 0);

Loops


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var bowlsOfPorridge = ['hot bowl', 'cold bowl', 'just right bowl'],
yummyPorridge = false,
i = bowlsOfPorridge.length - 1;

do {
yummyPorridge = isPorridgeTasty(bowlsOfPorridge[i]);
if (yummyPorridge) {
console.log(bowlsOfPorridge[i]);
}
i--;
} while (i >= 0);

Loops


What's wrong with this version?


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var bowlsOfPorridge = ['hot bowl', 'cold bowl', 'just right bowl'],
yummyPorridge = false,
i = bowlsOfPorridge.length - 1;

do {
yummyPorridge = isPorridgeTasty(bowlsOfPorridge[i]);
if (yummyPorridge) {
console.log(bowlsOfPorridge[i]);
}
i--;
} while (!yummyPorridge);

Loops


What difference does a while loop make versus do-while?


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var bowlsOfPorridge = ['hot bowl', 'cold bowl', 'just right bowl'],
yummyPorridge = false,
i = bowlsOfPorridge.length - 1;

while (i >= 0) {
yummyPorridge = isPorridgeTasty(bowlsOfPorridge[i]);
if (yummyPorridge) {
console.log(bowlsOfPorridge[i]);
}
i--;
}

Break


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var bowlsOfPorridge = ['scalding bowl', 'moldy bowl', 'just right bowl', 'poisoned bowl', 'hot bowl', 'cold bowl', 'stinky bowl'],
yummyPorridge = false,
numBowls = bowlsOfPorridge.length,
i = 0;

while (i < numBowls) {
yummyPorridge = isPorridgeTasty(bowlsOfPorridge[i]);
console.log("Tasted " + bowlsOfPorridge[i]);
if (yummyPorridge) {
console.log("There is at least one bowl of yummy porridge on this table!");
break;
}
i++;
}

Break


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var firstTableBowlsOfPorridge = ['scalding bowl', 'moldy bowl', 'just right bowl', 'poisoned bowl'],
secondTableBowlsOfPorridge = ['hot bowl', 'cold bowl', 'stinky bowl', 'just right bowl'],
tables = [firstTableBowlsOfPorridge, secondTableBowlsOfPorridge];
yummyPorridge = false,
numTables = tables.length,
i = 0;

checkTables: while (i < numTables) {
var j = 0, numBowls = tables[i].length;
checkBowls: while (j < numBowls) {
yummyPorridge = isPorridgeTasty(tables[i][j]);
console.log("Tasted " + tables[i][j]);
if (yummyPorridge) {
console.log("There is at least one bowl of yummy porridge on table " + (i + 1) + "!"); // Why do we wrap i + 1 in parentheses?
break checkBowls;
}
j++;
}
i++;
}

Continue


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

var firstTableBowlsOfPorridge = ['scalding bowl', 'moldy bowl', 'just right bowl', 'poisoned bowl'],
secondTableBowlsOfPorridge = ['hot bowl', 'cold bowl', 'stinky bowl', 'just right bowl'],
tables = [firstTableBowlsOfPorridge, secondTableBowlsOfPorridge];
yummyPorridge = false,
numTables = tables.length,
i = 0;

checkTables: while (i < numTables) {
var j = 0, numBowls = tables[i].length;
checkBowls: while (j < numBowls) {
yummyPorridge = isPorridgeTasty(tables[i][j]);
console.log("Tasted " + tables[i][j]);
if (yummyPorridge) {
console.log("There is at least one bowl of yummy porridge on table " + (i + 1) + "!");
i++; // Why is this line necessary?
continue checkTables;
}
j++;
}
i++;
}



Break
(The other kind)

Functions

Functions provide variable scope.


var isPorridgeTasty = function(bowl) {
console.log(bowl); // Works fine
return (bowl === 'just right bowl');
};

isPorridgeTasty('frozen bowl');
console.log(bowl); // Causes ReferenceError

Functions

Variables are hoisted within functions. In other words, they are treated as if they were declared at the beginning of the function, but not with values assigned.


var breakIntoHouse = function() {
var task1 = "eat porridge";
console.log(task1); // "eat porridge"
console.log(task2); // undefined
console.log(task3); // ReferenceError
var task2 = "ruin chairs";
return task1 + ", then " + task2;
}
breakIntoHouse();

Functions


// This version:
var breakIntoHouse = function() {
var task1 = "eat porridge";
console.log(task1); // "eat porridge"
console.log(task2); // undefined
var task2 = "ruin chairs";
return task1 + ", then " + task2;
}
breakIntoHouse();

// ...is equivalent to this version:
var breakIntoOtherHouse = function() {
var task1 = "eat porridge", task2;
console.log(task1); // "eat porridge"
console.log(task2); // undefined
task2 = "ruin chairs";
return task1 + ", then " + task2;
}
breakIntoOtherHouse();

Functions

To reduce confusion, declare all variables at top of function.


var breakIntoHouse = function() {
var task1 = "eat porridge", task2 = "ruin chairs";
console.log(task1);
console.log(task2);
return task1 + ", then " + task2;
}
breakIntoHouse();

Functions

Functions are first-class objects.

  • Can be assigned to variables.
  • Can be passed as arguments to other functions.
  • Can be returned from other functions.
  • Can have their own properties and methods.

Functions

Functions can be assigned to variables.


var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

Functions

You can define a function using a "function declaration" or a "function expression."


// Function declaration
function isPorridgeTasty(bowl) {
return (bowl === 'just right bowl');
}

// Function expression (anonymous function)
var isPorridgeTasty = function(bowl) {
return (bowl === 'just right bowl');
};

// Named function expression
var isPorridgeTasty = function isPorridgeTasty(bowl) {
return (bowl === 'just right bowl');
};

Functions


// You can bind a function to a variable name that is different
// from the function name.

var isPorridgeTasty = function doILikeThePorridge(bowl) {
return (bowl === 'just right bowl');
};
console.log(isPorridgeTasty('icky bowl')); // false
console.log(doILikeThePorridge('nasty bowl')); // ReferenceError

Functions

Named function expressions are often used for debugging.



var isPorridgeTasty = function doILikeThePorridge(bowl) {
console.log(isPorridgeTasty.name); // doILikeThePorridge
console.log(doILikeThePorridge.name); // doILikeThePorridge
return (bowl === 'just right bowl');
};
isPorridgeTasty('icky bowl');

console.log(isPorridgeTasty.name); // doILikeThePorridge
console.log(doILikeThePorridge.name) // ReferenceError

Functions

Functions can be passed as arguments to other functions.


var bowls = [
{name: "cold porridge", empty: false},
{name: "hot porridge", empty: false},
{name: "just right porridge", empty: false}
],
chairs = [
{name: "hard chair", broken: false},
{name: "soft chair", broken: false},
{name: "just right chair", broken: false}
],
houseContents = {"bowls": bowls, "chairs": chairs};

var breakIntoHouse = function() {
var houseContents = arguments[0],
numCallbacks = arguments.length - 1,
i = 1;

for (i; i <= numCallbacks; i++) {
if (typeof arguments[i] === "function") {
arguments[i](houseContents);
}
}
};
var eatPorridge = function(houseContents) {
if (typeof houseContents.bowls === "object") {
for (i in houseContents.bowls) {
houseContents.bowls[i].empty = true;
}
}
}
breakIntoHouse(houseContents, eatPorridge);
console.log(houseContents);

Functions


What are some examples of callbacks you have seen in your experience with JavaScript?

Functions

Functions can return other functions. This situation can result in closures.


 var wreakHavoc = function(verb, directObject) {
var i = 1,
havoc = function() {
var j = i;
i++;
return "Goldilocks " + verb + " " + j + " " + directObject;
};

return havoc;
}
var stealPorridge = wreakHavoc("devoured", "bowls of porridge");
// variable i persists from one invocation to the next
console.log(stealPorridge()); // Goldilocks devoured 1 bowls of porridge
console.log(stealPorridge()); // Goldilocks devoured 2 bowls of porridge
console.log(stealPorridge()); // Goldilocks devoured 3 bowls of porridge

Functions


var wreakHavoc = function(verb, directObject) {
var i = 1,
havoc = function() {
var j = i;
i++;
return "Goldilocks " + verb + " " + j + " " + directObject;
};

return havoc;
}
var stealPorridge = wreakHavoc("devoured", "bowls of porridge");
console.log(stealPorridge()); // Goldilocks devoured 1 bowls of porridge
console.log(stealPorridge()); // Goldilocks devoured 2 bowls of porridge
console.log(stealPorridge()); // Goldilocks devoured 3 bowls of porridge
var breakChairs = wreakHavoc("smashed", "chairs");

// What will these return?
console.log(breakChairs());
console.log(breakChairs());




Break

Hoisting Review




Net Tuts Video

Closures Review


Read "How do JavaScript closures work?" and, individually or in small groups, create your own examples of closures. Present your examples to the rest of the class.

Lab Time


Start on reading and homework for next week, and meet with Dan about mid-term presentation topics.

WDIM387 Week 2JavaScript functions

By danmuzyka

WDIM387 Week 2JavaScript functions

  • 1,457