// The variable square is being set to a function
// that has one parameter, x.
var square = function(x) { // Opening brace
return x * x; // Function body
}; // Closing brace
console.log(square(12));
// → 144
A function definition is just a regular variable definition where the value given to the variable happens to be a function.
A function starts with the keyword function, can have have a set of parameters and a body which is wrapped in curly braces {}.
var square = function(x) {
return x * x; // produce a value
};
console.log(square(12));
// → 144
var makeNoise = function() {
console.log("Pling!"); // side-effect
};
makeNoise();
// → Pling!
Some functions produce a value
while others produce a side effect.
A return statement determines the value the function returns and it immediately jumps out of the current function.
The return keyword without an expression after it will cause the function to return undefined.
Parameters to a function behave like regular variables, but their initial values are given by the caller of the function, not the code in the function itself
Variables created inside a function including their parameters, are local to the function.
This “localness” of variables applies only to the parameters and to variables declared with the var keyword
inside the function body.
Variables declared outside of any function are called global, and can be accessed anywhere.
var square = function(x) {
return x * x; // produce a value
};
console.log(square(12));
// → 144
var x = "outside";
var f1 = function() {
var x = "inside f1";
};
f1();
console.log(x);
// → outside
var f2 = function() {
x = "inside f2";
};
f2();
console.log(x);
// → inside f2
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 += "\\";
};
flat(3);
mountain(4);
flat(6);
mountain(1);
flat(1);
return result;
};
console.log(landscape());
// → ___/''''\______/'\_
Functions can be created inside other functions, producing several degrees of locality.
Function variables usually simply act as names for a specific piece of the program. Such a variable is defined once and never changed. This makes it easy to start confusing the function and its name.
var func = function() {};
function variable: Left side of the equation.
function value: Right side of the equation.
But the two are different. A function value can do all the things that other values can do—you can use it in arbitrary expressions, not just call it.
It is possible to store a function value in a new place, pass it as an argument to a function, and so on.
Similarly, a variable that holds a function is still just a regular variable and can be assigned a new value.
var launchMissiles = function(value) {
missileSystem.launch("now");
};
if (safeMode)
launchMissiles = function(value) {/* do nothing */};
The function keyword can also be used at the start of a statement.
function square(x) {
return x * x;
}
console.log("The future says:", future());
function future() {
return "We STILL have no flying cars.";
}
This is a function declaration
There is one subtlety with this form of
function definition.
The function is hoisted to the top of the scope.
alert("Hello", "Good Evening", "How do you do?");
The function alert officially accepts only one argument. When you call it like this, it doesn’t complain. It simply ignores the other arguments and shows you “Hello”.
JavaScript is extremely broad-minded about the number of arguments you pass to a function.
If you pass too many, the extra ones are ignored.
If you pass too few, the missing parameters simply get assigned the value undefined.
The upside:
This behavior can be used to have a function take “optional” arguments.
The downside:
It is possible—likely, even—that you’ll accidentally pass the wrong number of arguments to functions and no one will tell you about it.
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
power can be called either with two arguments or with a single argument,
in which case the exponent is assumed to be two, and the function behaves like square.
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
What happens to local variables when the function call that created them is no longer active?
This feature—being able to reference a specific instance of local variables in an enclosing function—is called closure.
A function that “closes over” some local variables is called a closure.
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
var twice = multiplier(2);
console.log(twice(5));
// → 10
With a slight change, we can turn the previous example into a way to create functions that multiply by an arbitrary amount.
A good mental model is to think of the function keyword as “freezing” the code in its body and wrapping it into a package (the function value). So when you read return function(...) {...}, think of it as returning a handle to a piece of computation, frozen for later use.
var twice = multiplier(2);
// Step 1
function multiplier(2) {
return function(number) {
return number * 2;
};
}
console.log(twice(5));
// Step 1
var twice = function(number) {
return number * 2;
};
// Step 2
function(number) {
return number * 2;
}
// Step 3
function(5) {
return 5 * 2;
}
// → 10
function power(base, exponent) {
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}
console.log(power(2, 3));
// → 8
It is perfectly okay for a function to call itself,
as long as it takes care not to overflow the stack.
A function that calls itself is called recursive.
Recursion is a complicated concept and is best covered somewhere else.
There are 2 general ways functions get added to a program.
How difficult it is to find a good name for a function is a good indication of how clear a concept it is that you’re trying to wrap.
How smart and versatile should our function be?
A useful principle is not to add cleverness unless you are absolutely sure you’re going to need it.
Functions can be roughly divided into types:
1)Those that are called for their side effects.
2)Those that are called for their return value.
console.log has the side affect of
printing something to the console.
A pure function is one that
given the same input will always return the same result.
Math.abs(-1) will always return 1
Pure functions are easy to test.
When used as a statement, it can be used to declare a variable and give it a function as its value.
// Create a function value f
var f = function(a) {
console.log(a + 2);
};
// Declare g to be a function
function g(a, b) {
return a * b * 3.5;
}