jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
jfraboni edited this page Dec 22, 2014 · 11 revisions

You should understand [Variables](Variables & Constants)

A function is any amount of code that is grouped together. You can use a variable to reference that code and in the future run it just by "invoking" that variable.

Syntax

// This is a function that will print out hi to the consolevarsayHi=function(){console.log("Hi there everyone");}// You can invoke it like this (there are several other ways to invoke it too)sayHi();// you can pass parameters into a function and it can be as many lines as you want (though fewer is better)varsayHiInformally=function(firstName){varmessage="Whats up "+firstName+" we're both cool.";console.log(message);}// You can invoke functions from inside other functions and functions can return values!vargetSalutation=function(firstName){if(firstName=="David"){return"Mr.";}if(firstName=="John"){return"Mr.";}return"Mrs.";//Otherwise return Mrs}varsayHiFormally=function(firstName){varmessage="Greetings "+getSalutation(firstName)+" "+firstName;console.log(message);}sayHiFormally("John");//will print "Greetings Mr. John"sayHiFormally("Johanna");//will print "Greetings Mrs. Johanna"// A function declared this way (named function) will be visible everywhere in its scopefunctionsuperFormalHi(firstName){console.log("Pleasure to meet you "+getSalutation(firstName)+" "+firstName);}// This can be invoked like normalsuperFormalHi("Donna");

Why Functions?

Suppose you have some code for driving the car to the store

car.turnOnEngine();car.driveForward();if(stoplight1.isRed){car.stop();car.waitForGreen(stoplight1);car.driveForward();}car.turnLeft();car.driveForward();if(stoplight2.isRed){car.stop();car.waitForGreen(stoplight2);car.driveForward();}// ...

Notice what happens every time you hit a stoplight - you have to check if it's read, and if so stop and wait for green before continuing. And we have to do that at every single stoplight! What if there's ten stoplights on the way to the store? We can copy this code ten times of course. What if we later want to cautiously stop when the stoplight is yellow as well? Then we have to remember to change every...single...one.

So we write a quick function so that all of that code is in one place and easy to change in the future.

var handleStoplight = function(stoplight) {
if(stoplight.isRed) {
car.stop();
car.waitForGreen(stoplight2);
car.driveForward();
}
}

we can now use it over and over again handleStoplight(stoplight1);, handleStoplight(stoplight2);, etc.`

This concept is incredibly important to oganizing code. In fact, it turns out that functions are quite possible the most important concept in javascript. Just like simple atoms combine to make the complex objects around us, it turns out simple functions can be combined to make fantastically sophisticated programming structures.

But first let's talk about some of the aspects of functions.

Function Scope

Consider the following code

vargreeting="What's Up";varsayHi=function(){vargreeting="Hi";console.log(greeting);}sayHi();console.log(greeting);

As you might intuitively suspect, this will print

Hi
What's Up

This is because variables created inside of a function exist only inside of that function. This is called function scope and is one of the most important concepts in javascript. It also means that you get results like this

Runnable Function Scope Example

vardoStuff=function(){varinformal="Hi";varsayHi=function(){varformal="Hello";console.log(informal);// prints "Hi"}sayHi();console.log(informal);// prints "Hi"console.log(formal);// ReferenceError - formal does not exist}doStuff();

Again, this should make intuitive sense. Inside of sayHi we can refer to the informal variable because both informal and the body of sayHi are inside the doStuff function. However, since the formal variable is inside of sayHi and the console.log(formal) line is not, we get an error.

When in doubt, just look up through the levels of indentation. If you want to know if a variable is visible to a particular line of code, tilt your head to the left and imagine the code is a landscape. Can you get from that line to the variable without climbing downhill?

Rotate code and picture as landscape

Consider the usage of the informal variable on line 6 above. Where is the declaration of informal that this relates to? Well start at line 6 and start climbing in both directions, never move downhill - jump over any canyons. The first var informal you encounter (on line 2) is the declaration.

Notice that this is why the reference to the formal variable on line 11 results in an error - moving upwards we never encounter a var formal!

Global Scope

Immediately Invoked Functions

Functions As Paramters

Named Functions (and Function Hoisting)

Functions That Return Functions

Advanced Concepts

Functions Are Objects

You should understand Objects

Like most things in javascript, functions are objects. That means that they can have properties and methods! function with properties.

Therefore, like other objects, all functions have a .toString, and several other methods. They follow the same prototype inheritence rules as objects and can be used in the same way.

varx=function(){};x.firstName="Fred";x.lastName="Flintstone";

Most of the time this will be a curiousity and you will not need to use functions as objects. But there are some features that rely on the fact that they can be used in this way.

.call and .apply

this Context Parameter

Function Constructors

Partial Application with .bind

arguments


Functions are a group of statements executed one after another within their own subprogram - think of them like a program within a program. A function can have parameters, that is, when you define a function, you can specify a required list inputs. Importantly, they can also define a return value. In JavaScript, essentially everything is an object, and same goes for functions, and because of this they are deemed "first-class-objects", so they can be stored in variables, passed as arguments to other functions, created within functions, and returned from functions.

Named Functions

To declare or define a named function, we use the keyword, function, followed by a name we give the function. Functions are often by convention named using a verb, because usually they encapsulate the steps required to do somehthing. In short, think of functions as a way to define actions or ask for the state of something, like saveImage();, or, isComplete();.

Here's a very simple function that specifies two parameters and returns the sum of those two parameters:

functionadd(a,b){returna+b;}

This is called a named function, because we're giving it the name add. If we name the function, we can execute it again later in the program by its name.

So once declared, we can then execute it by stating its name, followed by open and closed parentheses () and passing arguments to meet the required parameters. You might also say, instead of execute, invoke, call, or run a function - those terms are synonymous when we speak about executing a function. Here's what executing one looks like:

/* * Here, when we define the add function, a and b are called parameters: */functionadd(a,b){returna+b;}/* * Here, when we execute the add function, the values 5 and 5 are  * called arguments, which we are passing into the add function:  */varsum=add(5,5);console.log(sum);// prints 10;

One thing that often confuses people is the different in nomenclature between parameters and arguments. In the above example, at the point of defining the add function, we specify that the function takes two parameters, a and b. At the point of executing the function, we pass in two arguments, the values 5 and 5. See the comments we've added, above.

By encapsulating a series of statements together, we can reuse the functionality of the steps within the function elsewhere in a program without having to redefine those steps. This helps keep a program more organized and aids in maintainability. Imagine a more complex function:

functionisPointInPolygon(point,p){varx=point[0],y=point[1];varinside=false;for(vari=0,j=p.length-1;i<p.length;j=i++){varxi=p[i][0],yi=p[i][1];varxj=p[j][0],yj=p[j][1];varintersect=((yi>y)!=(yj>y))&&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);if(intersect)inside=!inside;}returninside;};

If you later find a better way of expressing this functionality, or if you discovered a bug in your code, by encapsulating these series of statements together in a function, you need only change the code in one place to upgrade or fix its functionality. This form of reuse is described be the D.R.Y principle in design: Don't repeat yourself.

Anonymous Functions

Functions can also be defined anonymously, that is, without a name:

setTimeout(function(){console.log("Time up!");},1000);

Here, we're executing the built-in setTimeout function, which runs a timer for a specified number of milliseconds, in this case for 1 second. The first parameter of the setTimeout requires us to pass a callback function to be executed once the timer completes, and the second parameter is the number of milliseconds for which the timer will run. In this example, we've defined the callback function inline, without a name, so it is termed an anonymous function.

This example will run a timer for one second, then execute the anonymous callback function, which in turn will call the console.log function, and print the message "Times up!". Because there's no other reference to the callback function, that is, it's not assigned to a variable, and it was not declared with a name, once the timer runs out and the callback function is executed, it is no longer in memeory. This is a powerful pattern you'll see a lot in more advanced JavaScript applications.

Scope

Scope implies what is accessible where. Functions encapsulate their own scope, and functions within functions do the same, but we call those closures. To understand scope, imagine a room within a room, and people in the inner room can see into the outer room, but the people in the outer room cannot see the people inside the inner room. Functions form a closure around themselves to have their own little environment, and variables and values within that closure or scope cannot be seen or accessed outside that function unless the function returns the values:

varx=1;functiondoSomething(){console.log('Starting doSomething...');console.log(x);// prints 1x+=1;console.log(x);// prints 2vary=2;console.log(y);// prints 2console.log('Exiting doSomething...');}console.log(x);// prints 1doSomething();// see notes inside doSomething()...console.log(x);// prints 2console.log(y);// throws a ReferenceError: y is not defined

In this example, x is visible inside the function doSomething() when it is executed, but the variable y, which is declared and initialized inside the function doSomething(), is not visible outside of the function doSomething().

© 2014-2015 Operation Spark

Clone this wiki locally