Created
January 23, 2015 08:26
-
-
Save alex-dixon/96c79e74cae63a2058d3 to your computer and use it in GitHub Desktop.
Eloquent Javascript - Chapter 3 // source http://jsbin.com/cuxina
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="Eloquent Javascript - Chapter 3" /> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<script id="jsbin-javascript"> | |
/* Chapter 3: Functions | |
are words you create | |
-or- | |
Programs inside programs | |
*/ | |
var power = function(base, exponent) { | |
var result = 1; // local variable declaration...creates 'result' every time function is run | |
// note how 'for' loop omits {} | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
}; | |
console.log(power(2, 10)); | |
// << return >> defines the value the function returns | |
// Global and local | |
var x = "outside"; | |
var f1 = function() { | |
var x = "inside f1"; // << var >> is for declaring, local inside function | |
}; | |
f1(); | |
console.log(x); | |
// "outside" | |
var f2 = function() { | |
x = "inside f2"; // variable without << var >> changes existing variable | |
}; | |
f2(); | |
console.log(x); | |
// "inside f2" | |
// Functions Within Functions | |
// or Nested Scope | |
var landscape = function() { | |
var result = ""; | |
var flat = function(size) { | |
for (var count = 0; count < size; count++) | |
result += "_"; | |
}; | |
var mountain = function(size) { | |
result += "/"; | |
for (var count = 0; count < size; count++) | |
result += "'"; | |
result += "\\"; // evaluates to escape + '\' | |
}; | |
flat(3); | |
mountain(4); | |
flat(6); | |
mountain(1); | |
flat(1); | |
return result; | |
}; | |
console.log(landscape()); | |
// ___/''''\______/'\_ | |
// Here, 'flat' and 'mountain' can both access the result variable because it is defined outside or 'above' both of them. Note both functions are on same level as each other so there is no hierarchical order like exists between them and 'landscape' | |
// Functions As Values | |
// "Function variables ...act as names for a specific piece of the program." | |
var launchMissiles = function(value) { | |
missileSystem.launch("now"); | |
}; | |
if (safeMode) | |
launchMissles = function(value) {/* do nothing */}; | |
// Declaration Notation | |
function square(x) { | |
return x * x; | |
} | |
// ... Why does it matter? ... | |
console.log("The future says:", future()); | |
// defined below it being called & works because of this notation | |
function future() { | |
return "We STILL have no flying cars."; | |
} | |
// When not to use? Inside an 'if' statement | |
// e.g. : | |
function example() { | |
function a() {} // < -- good | |
if (something) { | |
function b() {} // < -- BAD! Don't use this notation inside an 'if' statement ever! | |
} | |
} | |
// The Call Stack | |
// What's the execution order? | |
function greet(who) { | |
console.log("Hello " + who); | |
} | |
greet("Harry"); | |
console.log("Bye"); | |
// 1. line 3 | |
// 2. line 2 / start of function | |
// 3. line 2 / console.log | |
// 4. function ends, computer returns to line that called function | |
// 5. console.log | |
// The 'call stack' is basically the computer's representation of the hierarchical order of a program and its functions | |
// Optional Arguments -or- On Arguments | |
// they default to 'undefined' | |
function power(base, exponent) { | |
if (exponent === undefined) | |
exponent = 2; | |
var result = 1; | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
} | |
console.log(power(4)); | |
// 16 | |
console.log(power(4, 3)); | |
// 64 | |
// Closure | |
// 'What happens to local variables when the function call that created them is no longer active?' | |
function wrapValue(n) { | |
var localVariable = n; | |
return function() { return localVariable; }; | |
} | |
var wrap1 = wrapValue(1); | |
var wrap2 = wrapValue(2); | |
console.log(wrap1()); | |
// 1 | |
console.log(wrap2()); | |
// 2 | |
// So it creates a local variable from its parameter. Then returns an anonymous function that returns that variable. Note: Works because local variables are created for every | |
function multiplier(factor) { | |
return function(number) { | |
return number * factor; | |
}; | |
} | |
var twice = multiplier(2); // 'multiplier' returns CODE...FROZEN CODE. In this case it is the body of the anonymous function. | |
// when stored in variable ('twice') : the anon function can still access 'factor' as it was stored into the variable ('twice') | |
console.log(twice(5)); | |
// 10 | |
// Recursion | |
// -or- A function calls itself | |
function power(base, exponent) { | |
if (exponent === 0) | |
return 1; | |
else | |
return base * power(base, exponent - 1); | |
} | |
console.log(power(2, 4)); | |
// 8 | |
// Since that's hard to follow consider this... | |
// Since "that's" hard to follow, consider this... | |
// and now for something completley different | |
// program that prints num of cows & chickens | |
function printFarmInventory(cows, chickens) { | |
var cowString = String(cows); | |
while (cowString.length < 3) | |
cowString = "0" + cowString; | |
console.log(cowString + " Cows"); | |
var chickenString = String(chickens); | |
while (chickenString.length < 3) | |
chickenString = "0" + chickenString; | |
console.log(chickenString + " Chickens"); | |
} | |
printFarmInventory(7, 11); | |
// Wiiiiiiith.....re-cursion! | |
function printZerpPaddedWithLabel(number, label) { | |
var numberString = String(number); | |
while (numberstring.length < 3) | |
numberString = "0" + numberString; | |
console.log(numberString + " " + label); | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
printZeroPaddedWithLabel(cows, "Cows"); | |
printZeroPaddedWithLabel(chickens, "Chickens"); | |
printZeroPaddedWithLabel(pigs, "Pigs"); | |
} | |
printFarmInventory(7, 11, 3); | |
// refactored with a function that returns instead of having a side effect | |
function zeroPad(number, width) { | |
var string = String(number); | |
while (string.length < width) | |
string = "0" + string; | |
return string; | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
console.log(zeroPad(cows, 3) + " Cows"); | |
console.log(zeroPad(chickens, 3) + " Chickens"); | |
console.log(zeroPad(pigs, 3) + " Pigs"); | |
} | |
printFarmInventory(7, 16, 3); | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">/* Chapter 3: Functions | |
are words you create | |
-or- | |
Programs inside programs | |
*/ | |
var power = function(base, exponent) { | |
var result = 1; // local variable declaration...creates 'result' every time function is run | |
// note how 'for' loop omits {} | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
}; | |
console.log(power(2, 10)); | |
// << return >> defines the value the function returns | |
// Global and local | |
var x = "outside"; | |
var f1 = function() { | |
var x = "inside f1"; // << var >> is for declaring, local inside function | |
}; | |
f1(); | |
console.log(x); | |
// "outside" | |
var f2 = function() { | |
x = "inside f2"; // variable without << var >> changes existing variable | |
}; | |
f2(); | |
console.log(x); | |
// "inside f2" | |
// Functions Within Functions | |
// or Nested Scope | |
var landscape = function() { | |
var result = ""; | |
var flat = function(size) { | |
for (var count = 0; count < size; count++) | |
result += "_"; | |
}; | |
var mountain = function(size) { | |
result += "/"; | |
for (var count = 0; count < size; count++) | |
result += "'"; | |
result += "\\"; // evaluates to escape + '\' | |
}; | |
flat(3); | |
mountain(4); | |
flat(6); | |
mountain(1); | |
flat(1); | |
return result; | |
}; | |
console.log(landscape()); | |
// ___/''''\______/'\_ | |
// Here, 'flat' and 'mountain' can both access the result variable because it is defined outside or 'above' both of them. Note both functions are on same level as each other so there is no hierarchical order like exists between them and 'landscape' | |
// Functions As Values | |
// "Function variables ...act as names for a specific piece of the program." | |
var launchMissiles = function(value) { | |
missileSystem.launch("now"); | |
}; | |
if (safeMode) | |
launchMissles = function(value) {/* do nothing */}; | |
// Declaration Notation | |
function square(x) { | |
return x * x; | |
} | |
// ... Why does it matter? ... | |
console.log("The future says:", future()); | |
// defined below it being called & works because of this notation | |
function future() { | |
return "We STILL have no flying cars."; | |
} | |
// When not to use? Inside an 'if' statement | |
// e.g. : | |
function example() { | |
function a() {} // < -- good | |
if (something) { | |
function b() {} // < -- BAD! Don't use this notation inside an 'if' statement ever! | |
} | |
} | |
// The Call Stack | |
// What's the execution order? | |
function greet(who) { | |
console.log("Hello " + who); | |
} | |
greet("Harry"); | |
console.log("Bye"); | |
// 1. line 3 | |
// 2. line 2 / start of function | |
// 3. line 2 / console.log | |
// 4. function ends, computer returns to line that called function | |
// 5. console.log | |
// The 'call stack' is basically the computer's representation of the hierarchical order of a program and its functions | |
// Optional Arguments -or- On Arguments | |
// they default to 'undefined' | |
function power(base, exponent) { | |
if (exponent === undefined) | |
exponent = 2; | |
var result = 1; | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
} | |
console.log(power(4)); | |
// 16 | |
console.log(power(4, 3)); | |
// 64 | |
// Closure | |
// 'What happens to local variables when the function call that created them is no longer active?' | |
function wrapValue(n) { | |
var localVariable = n; | |
return function() { return localVariable; }; | |
} | |
var wrap1 = wrapValue(1); | |
var wrap2 = wrapValue(2); | |
console.log(wrap1()); | |
// 1 | |
console.log(wrap2()); | |
// 2 | |
// So it creates a local variable from its parameter. Then returns an anonymous function that returns that variable. Note: Works because local variables are created for every | |
function multiplier(factor) { | |
return function(number) { | |
return number * factor; | |
}; | |
} | |
var twice = multiplier(2); // 'multiplier' returns CODE...FROZEN CODE. In this case it is the body of the anonymous function. | |
// when stored in variable ('twice') : the anon function can still access 'factor' as it was stored into the variable ('twice') | |
console.log(twice(5)); | |
// 10 | |
// Recursion | |
// -or- A function calls itself | |
function power(base, exponent) { | |
if (exponent === 0) | |
return 1; | |
else | |
return base * power(base, exponent - 1); | |
} | |
console.log(power(2, 4)); | |
// 8 | |
// Since that's hard to follow consider this... | |
// Since "that's" hard to follow, consider this... | |
// and now for something completley different | |
// program that prints num of cows & chickens | |
function printFarmInventory(cows, chickens) { | |
var cowString = String(cows); | |
while (cowString.length < 3) | |
cowString = "0" + cowString; | |
console.log(cowString + " Cows"); | |
var chickenString = String(chickens); | |
while (chickenString.length < 3) | |
chickenString = "0" + chickenString; | |
console.log(chickenString + " Chickens"); | |
} | |
printFarmInventory(7, 11); | |
// Wiiiiiiith.....re-cursion! | |
function printZerpPaddedWithLabel(number, label) { | |
var numberString = String(number); | |
while (numberstring.length < 3) | |
numberString = "0" + numberString; | |
console.log(numberString + " " + label); | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
printZeroPaddedWithLabel(cows, "Cows"); | |
printZeroPaddedWithLabel(chickens, "Chickens"); | |
printZeroPaddedWithLabel(pigs, "Pigs"); | |
} | |
printFarmInventory(7, 11, 3); | |
// refactored with a function that returns instead of having a side effect | |
function zeroPad(number, width) { | |
var string = String(number); | |
while (string.length < width) | |
string = "0" + string; | |
return string; | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
console.log(zeroPad(cows, 3) + " Cows"); | |
console.log(zeroPad(chickens, 3) + " Chickens"); | |
console.log(zeroPad(pigs, 3) + " Pigs"); | |
} | |
printFarmInventory(7, 16, 3); | |
</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Chapter 3: Functions | |
are words you create | |
-or- | |
Programs inside programs | |
*/ | |
var power = function(base, exponent) { | |
var result = 1; // local variable declaration...creates 'result' every time function is run | |
// note how 'for' loop omits {} | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
}; | |
console.log(power(2, 10)); | |
// << return >> defines the value the function returns | |
// Global and local | |
var x = "outside"; | |
var f1 = function() { | |
var x = "inside f1"; // << var >> is for declaring, local inside function | |
}; | |
f1(); | |
console.log(x); | |
// "outside" | |
var f2 = function() { | |
x = "inside f2"; // variable without << var >> changes existing variable | |
}; | |
f2(); | |
console.log(x); | |
// "inside f2" | |
// Functions Within Functions | |
// or Nested Scope | |
var landscape = function() { | |
var result = ""; | |
var flat = function(size) { | |
for (var count = 0; count < size; count++) | |
result += "_"; | |
}; | |
var mountain = function(size) { | |
result += "/"; | |
for (var count = 0; count < size; count++) | |
result += "'"; | |
result += "\\"; // evaluates to escape + '\' | |
}; | |
flat(3); | |
mountain(4); | |
flat(6); | |
mountain(1); | |
flat(1); | |
return result; | |
}; | |
console.log(landscape()); | |
// ___/''''\______/'\_ | |
// Here, 'flat' and 'mountain' can both access the result variable because it is defined outside or 'above' both of them. Note both functions are on same level as each other so there is no hierarchical order like exists between them and 'landscape' | |
// Functions As Values | |
// "Function variables ...act as names for a specific piece of the program." | |
var launchMissiles = function(value) { | |
missileSystem.launch("now"); | |
}; | |
if (safeMode) | |
launchMissles = function(value) {/* do nothing */}; | |
// Declaration Notation | |
function square(x) { | |
return x * x; | |
} | |
// ... Why does it matter? ... | |
console.log("The future says:", future()); | |
// defined below it being called & works because of this notation | |
function future() { | |
return "We STILL have no flying cars."; | |
} | |
// When not to use? Inside an 'if' statement | |
// e.g. : | |
function example() { | |
function a() {} // < -- good | |
if (something) { | |
function b() {} // < -- BAD! Don't use this notation inside an 'if' statement ever! | |
} | |
} | |
// The Call Stack | |
// What's the execution order? | |
function greet(who) { | |
console.log("Hello " + who); | |
} | |
greet("Harry"); | |
console.log("Bye"); | |
// 1. line 3 | |
// 2. line 2 / start of function | |
// 3. line 2 / console.log | |
// 4. function ends, computer returns to line that called function | |
// 5. console.log | |
// The 'call stack' is basically the computer's representation of the hierarchical order of a program and its functions | |
// Optional Arguments -or- On Arguments | |
// they default to 'undefined' | |
function power(base, exponent) { | |
if (exponent === undefined) | |
exponent = 2; | |
var result = 1; | |
for (var count = 0; count < exponent; count++) | |
result *= base; | |
return result; | |
} | |
console.log(power(4)); | |
// 16 | |
console.log(power(4, 3)); | |
// 64 | |
// Closure | |
// 'What happens to local variables when the function call that created them is no longer active?' | |
function wrapValue(n) { | |
var localVariable = n; | |
return function() { return localVariable; }; | |
} | |
var wrap1 = wrapValue(1); | |
var wrap2 = wrapValue(2); | |
console.log(wrap1()); | |
// 1 | |
console.log(wrap2()); | |
// 2 | |
// So it creates a local variable from its parameter. Then returns an anonymous function that returns that variable. Note: Works because local variables are created for every | |
function multiplier(factor) { | |
return function(number) { | |
return number * factor; | |
}; | |
} | |
var twice = multiplier(2); // 'multiplier' returns CODE...FROZEN CODE. In this case it is the body of the anonymous function. | |
// when stored in variable ('twice') : the anon function can still access 'factor' as it was stored into the variable ('twice') | |
console.log(twice(5)); | |
// 10 | |
// Recursion | |
// -or- A function calls itself | |
function power(base, exponent) { | |
if (exponent === 0) | |
return 1; | |
else | |
return base * power(base, exponent - 1); | |
} | |
console.log(power(2, 4)); | |
// 8 | |
// Since that's hard to follow consider this... | |
// Since "that's" hard to follow, consider this... | |
// and now for something completley different | |
// program that prints num of cows & chickens | |
function printFarmInventory(cows, chickens) { | |
var cowString = String(cows); | |
while (cowString.length < 3) | |
cowString = "0" + cowString; | |
console.log(cowString + " Cows"); | |
var chickenString = String(chickens); | |
while (chickenString.length < 3) | |
chickenString = "0" + chickenString; | |
console.log(chickenString + " Chickens"); | |
} | |
printFarmInventory(7, 11); | |
// Wiiiiiiith.....re-cursion! | |
function printZerpPaddedWithLabel(number, label) { | |
var numberString = String(number); | |
while (numberstring.length < 3) | |
numberString = "0" + numberString; | |
console.log(numberString + " " + label); | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
printZeroPaddedWithLabel(cows, "Cows"); | |
printZeroPaddedWithLabel(chickens, "Chickens"); | |
printZeroPaddedWithLabel(pigs, "Pigs"); | |
} | |
printFarmInventory(7, 11, 3); | |
// refactored with a function that returns instead of having a side effect | |
function zeroPad(number, width) { | |
var string = String(number); | |
while (string.length < width) | |
string = "0" + string; | |
return string; | |
} | |
function printFarmInventory(cows, chickens, pigs) { | |
console.log(zeroPad(cows, 3) + " Cows"); | |
console.log(zeroPad(chickens, 3) + " Chickens"); | |
console.log(zeroPad(pigs, 3) + " Pigs"); | |
} | |
printFarmInventory(7, 16, 3); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment