JS Fundamentals:
(and beyond!)
Classwork:
https://github.com/RebootJeff/jsFunctions
Presented by:
Jeff Lee
Curriculum by:
Bianca Gandolfo
Full-Stack JavaScriptivore
Hack Reactor VII
Curriculum Goddess
Hack Reactor OG
Review and solidify core JS principles with project.
Deep dive into how JS functions can be used.
Use fundamentals to grow as a JS coder.
(Learn prototype chain and OOP?)
var spitASickRhyme = function() {
console.log('I\'m in the pursuit of Princess Peach and I know');
console.log('When I think I\'ve won, she\'s in another castle');
};
// function EXPRESSION <(•_•^) and (v•_•)> function DECLARATION
function spitASickRhyme() {
console.log('I\'m in the pursuit of Princess Peach and I know');
console.log('When I think I\'ve won, she\'s in another castle');
}
var func = function(){
var local = true;
};
console.log(local);
var x = 'global!';
//inside a function
function addToGlobalScope(){
y = 'global here, too!';
}
//inside a function
function addToGlobalScope(){
y = 'global here, too!';
window.z = 'also global!';
// `window` is for browsers only
// (not Node.js)
}
REMEMBER: z and y are not declared until addToGlobalScope is called.
var g = 'global';
// Side note: `blender` is in global scope too
function blender(fruit) {
var y = 'yogurt';
function mix() {
alert( fruit + ' and ' + y + ' makes ' +
fruit + ' swirl');
}
mix();
}
blender('blueberry');
What happens when there is a child function nested within a parent function??
When are scopes actually created?
The scope of a function is created when the function is called.
var g = "global";
function go() {
var l = "local";
var g = "in here!";
alert(l + " inside local");
alert(g + " inside go");
}
go();
alert(g + " outside go");
var message = 'yes';
for(var i = 0; i < 5; i++){
var message = 'no';
};
console.log('Is there block scope? ' + message);
https://github.com/RebootJeff/jsFunctions
var closureAlert = function(){
var x = 'Help! I\'m a variable '+
'stuck in a closure!';
var alerter = function(){
alert(x);
};
alerter();
};
var closureAlert = function(){
var x = 0;
var alerter = function(){
x++;
alert(x);
};
return alerter;
};
var alerter1 = closureAlert();
var alerter2 = closureAlert();
alerter1();
alerter2();
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var addEleven = add(11);
var result = addEleven(22);
console.log(result);
function counter() {
var n = 0;
return {
count: function() { n++; return n; },
reset: function() { n = 0; }
};
};
var c = counter();
var d = counter();
c.count();
d.count();
c.reset();
c.count();
d.count();
1. Create your parent function.
2. Define some variables in the parent's local scope.
(they can be accessed by the child function)
3. Define a function inside the parent function.
(aka defining a "child" function or "nested" function)
4. Return that child from inside the parent.
function outerFunc() { var parentVar = "local to parent"; function innerFunc() { return parentVar + ' but accessed by child!'; }; return innerFunc; }
1. 2. 3. 4.
function outerFunc() {
var parentVar = "local to parent";
function innerFunc() {
return parentVar + ' but accessed by child!';
};
return innerFunc;
}
// STEP 1 - Run the parent function.
var example = outerFunc();
console.log(example);
// We see example now stores the child.
// STEP 2 - Run the child function.
var result = example();
console.log(result);
// What's the end result?
var sayAlice = function(){
var makeLog = function() {
console.log(alice);
};
var alice = 'Why hello there, Alice!';
return makeLog;
};
var log = sayAlice();
log();
var makeStopwatch = function(){
var elapsed = 0;
var stopwatch = function(){
return elapsed;
};
var increase = function(){ elapsed++; };
setInterval(increase, 1000);
return stopwatch;
};
var x = makeStopwatch();
var Module = function(){
var privateProperty = 'I like big fonts,' +
' and I cannot lie';
function privateMethod(params){
// do something
};
return {
publicProperty: 'JS rulez!!',
publicMethod: function(params){
// do something
},
privilegedMethod: function(params){
privateMethod(args);
}
};
};
var CarMaker = function(){
var brakeLightsOn = false, seatbeltLocked = false;
function useABS(pressure) {
// 1. Use Electronic Brakeforce Distribution.
// 2. If necessary, activate Stability Control.
// 3. Check if wheels are locking up.
// 4. If necessary, release and re-apply EBD.
}
return {
color: 'blue',
honkHorn: function() {
console.log('HONK!!!');
},
hitBrakes: function(pressure){
brakeLightsOn = true;
seatbeltLocked = true;
useABS(pressure);
}
};
};
Different format & new partners!
Quick Tip: When talking with your partner and TAs, practice using technical terminology. Be specific! Be precise!
var hello;
function foo() { }
var foo = function() {};
foo;
foo();
var woohoo = [1, 2, 3];
woohoo[i]
woohoo[0]
var yay = {
kool: 'aid'
};
kool
'aid'
kool: 'aid'
variable declaration (undefined variable)
function definition/declaration
function definition/expression
function, function reference
function call/invocation
element of woohoo, woohoo-sub-i
first element, woohoo-sub-0
key, property name
value, property value
key-value pair, property of yay
E.g., never say "thing";
specify which element of an array;
mention line numbers.
1. Take a function as an input (argument)
var time = 1;
setInterval(function(){
console.log(time++ + ' seconds have passed.');
}, 1000);
2. Return a function as the output
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
If a function does at least one of the following two things, then it is a baller higher-order function.
In JavaScript...
"higher-order" functions can exist because
JS treats functions as "first-class objects".
In other words...
functions can be:
...just like any other object in JS
(just like numbers, strings, booleans, arrays, etc).
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue();
} else {
isFalse();
}
};
ifElse(true,
function(){ console.log(true);},
function(){ console.log(false);}
);
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue();
} else {
isFalse();
}
};
var logTrue = function(){ console.log(true); };
var logFalse = function(){ console.log(false); };
ifElse(true, logTrue, logFalse);
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue(); // no arguments
} else {
isFalse(); // no arguments
}
};
var ifElse = function(condition, isTrue, isFalse, arg){
if(condition){
isTrue(arg); // Look! An argument! Whoa.
} else {
isFalse(arg); // <(^.^<) OMG it's another one.
}
};
var increment = function(n){
return n + 1;
};
var square = function(n){
return n*n;
};
var doMathSoIDontHaveTo = function(n, func){
return func(n);
};
doMathSoIDontHaveTo(5, square);
doMathSoIDontHaveTo(4, increment);
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue.apply(this, [].slice.call(arguments,3));
} else {
isFalse.apply(this, [].slice.call(arguments,3));
}
};
New partners!
(again)
A utility library that provides functional methods.
http://underscorejs.org/
http://underscorejs.org/docs/underscore.html
var pocketmons = ['Charisaur', 'Bulbazard', 'Twomew'];
var logger = function(val){
console.log(val);
};
_.each(pocketmons, logger);
//_.each(list, iterator)
aka _.forEach()
_.forEach(pocketmons, logger);
http://underscorejs.org/#each
var _ = {};
_.each = function(list, callback) {
if(Array.isArray(list)) {
for(var i = 0; i < list.length; i++) {
callback(list[i], i, list);
}
} else {
for(var key in list) {
callback(list[key], key, list);
}
}
};
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
var farm = [];
for(var i = 0; i < animalNames.length; i++){
farm.push(AnimalMaker(animalNames[i]));
}
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
var farm = [];
_.each(animalNames, function (name) {
farm.push(AnimalMaker(name));
});
var studentA = {
firstName: 'Ryan',
lastName: 'Gosling'
};
var classA = {
subject: 'JavaScript',
teacher: '@RebootJeff',
students: [ /* studentA, studentB, etc... */ ]
};
var classes = [ /* classA, classB, etc... */ ];
for(var i = 0; i < classes.length; i++) {
for(var j = 0; j < classes[i].students.length; j++) {
var fullName = classes[i].students[j].firstName +
' ' + classes[i].students[j].lastname;
console.log(fullName);
}
}
_.each(classes, function(class) {
_.each(class.students, function(student) {
var fullName = student.firstName + ' ' + student.lastName;
console.log(fullName);
});
});
How do we print all the names
of all the students
of all the classes?
for(var i = 0; i < classes.length; i++) {
var students = classes[i].students; // This improves readability
for(var j = 0; j < students.length; j++) {
var fullName = students[j].firstName + ' ' + students[j].lastname;
console.log(fullName);
}
}
MUCH easier to read:
var pocketmon = ['Charisaur', 'Bulbazard', 'Twomew'];
var stokedArr = function(val){
return val + '!!!';
};
var stokedPocketmon = _.map(pocketmon, stokedArr);
//_.map(list, iterator)
var _ = { each: function(/*...*/) { /*...*/ } };
_.map = function(list, iterator) {
var result = []; // make a new array
_.each(array, function(item, index, list) {
result.push(iterator(item, index, list));
});
return result;
};
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
var farm = [];
_.each(animalNames, function (name) {
farm.push(AnimalMaker(name));
});
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
var farm = _.map(animalNames, function (name) {
return AnimalMaker(name);
});
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
// Remember coding WITHOUT Underscore?
var farm = [];
for(var i = 0; i < animalNames.length; i++){
farm.push(AnimalMaker(animalNames[i]));
}
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['Frog', 'Falcon', 'Fox'];
// Mapping builds up an array and returns it.
var farm = _.map(animalNames, function (name) {
return AnimalMaker(name);
});
// An each loop returns nothing.
// Just use it to iterate over an array.
_.each(farm, function (animal) {
animal.speak();
});
I want to simply loop through an array or object.
I want a new array based on an existing one.
New partners!
(of course)
Extra Credit is available if you finish early.
Follow me @RebootJeff (I follow the 80% rule)
Read my words on RebootJeff.com (for coding + career advice)
Follow Bianca @BiancaGando (GDI)
then we can discuss other topics such as...
BUT... there are no slides or prepared materials for these topics.
(Treat this like a Q&A session)