A Pull of the Lever: Prefaces

Caffe Molinari

“Café Allongé, also called Espresso Lungo, is a drink midway between an Espresso and Americano in strength. There are two different ways to make it. The first, and the one I prefer, is to add a small amount of hot water to a double or quadruple Espresso Ristretto. Like adding a splash of water to whiskey, the small dilution releases more of the complex flavours in the mouth. “The second way is to pull an extra long double shot of Espresso. This achieves approximately the same ratio of oils to water as the dilution method, but also releases a different mix of flavours due to the longer extraction. Some complain that the long pull is more bitter and detracts from the best character of the coffee, others feel it releases even more complexity. “The important thing is that neither method of preparation should use so much water as to result in a sickly, pale ghost of Espresso. Moderation in all things.”

Foreword by Michael Fogus

As a life-long bibliophile and long-time follower of Reg’s online work, I was excited when he started writing books. However, I’m very conservative about books – let’s just say that if there was an aftershave scented to the essence of “Used Book Store” then I would be first in line to buy. So as you might imagine I was “skeptical” about the decision to release JavaScript Allongé as an ongoing ebook, with a pay-what-you-want model. However, Reg sent me a copy of his book and I was humbled. Not only was this a great book, but it was also a great way to write and distribute books. Having written books myself, I know the pain of soliciting and receiving feedback.

The act of writing is an iterative process with (very often) tight revision loops. However, the process of soliciting feedback, gathering responses, sending out copies, waiting for people to actually read it (if they ever do), receiving feedback and then ultimately making sense out of how to use it takes weeks and sometimes months. On more than one occasion I’ve found myself attempting to reify feedback with content that either no longer existed or was changed beyond recognition. However, with the Leanpub model the read-feedback-change process is extremely efficient, leaving in its wake a quality book that continues to get better as others likewise read and comment into infinitude.

In the case of JavaScript Allongé, you’ll find the Leanpub model a shining example of effectiveness. Reg has crafted (and continues to craft) not only an interesting book from the perspective of a connoisseur, but also an entertaining exploration into some of the most interesting aspects of his art. No matter how much of an expert you think you are, JavaScript Allongé has something to teach you… about coffee. I kid.

As a staunch advocate of functional programming, much of what Reg has written rings true to me. While not exclusively a book about functional programming, JavaScript Allongé will provide a solid foundation for functional techniques. However, you’ll not be beaten about the head and neck with dogma. Instead, every section is motivated by relevant dialog and fortified with compelling source examples. As an author of programming books I admire what Reg has managed to accomplish and I envy the fine reader who finds JavaScript Allongé via some darkened channel in the Internet sprawl and reads it for the first time.

Enjoy.

– Fogus, fogus.me

Foreword by Matthew Knox

A different kind of language requires a different kind of book.

JavaScript holds surprising depths–its scoping rules are neither strictly lexical nor strictly dynamic, and it supports procedural, object-oriented (in several flavors!), and functional programming. Many books try to hide most of those capabilities away, giving you recipes for writing JavaScript in a way that approximates class-centric programming in other languages. Not JavaScript Allongé. It starts with the fundamentals of values, functions, and objects, and then guides you through JavaScript from the inside with exploratory bits of code that illustrate scoping, combinators, context, state, prototypes, and constructors.

Like JavaScript itself, this book gives you a gentle start before showing you its full depth, and like a Cafe Allongé, it’s over too soon. Enjoy!

–Matthew Knox, mattknox.com

Why JavaScript Allongé?

JavaScript Allongé solves two important problems for the ambitious JavaScript programmer. First, JavaScript Allongé gives you the tools to deal with JavaScript bugs, hitches, edge cases, and other potential pitfalls.

There are plenty of good directions for how to write JavaScript programs. If you follow them without alteration or deviation, you will be satisfied. Unfortunately, software is a complex thing, full of interactions and side-effects. Two perfectly reasonable pieces of advice when taken separately may conflict with each other when taken together. An approach may seem sound at the outset of a project, but need to be revised when new requirements are discovered.

When you “leave the path” of the directions, you discover their limitations. In order to solve the problems that occur at the edges, in order to adapt and deal with changes, in order to refactor and rewrite as needed, you need to understand the underlying principles of the JavaScript programming language in detail.

You need to understand why the directions work so that you can understand how to modify them to work properly at or beyond their original limitations. That’s where JavaScript Allongé comes in.

JavaScript Allongé is a book about programming with functions, because JavaScript is a programming language built on flexible and powerful functions. JavaScript Allongé begins at the beginning, with values and expressions, and builds from there to discuss types, identity, functions, closures, scopes, and many more subjects up to working with classes and instances. In each case, JavaScript Allongé takes care to explain exactly how things work so that when you encounter a problem, you’ll know exactly what is happening and how to fix it.

Second, JavaScript Allongé provides recipes for using functions to write software that is simpler, cleaner, and less complicated than alternative approaches that are object-centric or code-centric. JavaScript idioms like function combinators and decorators leverage JavaScript’s power to make code easier to read, modify, debug and refactor, thus avoiding problems before they happen.

JavaScript Allongé teaches you how to handle complex code, and it also teaches you how to simplify code without dumbing it down. As a result, JavaScript Allongé is a rich read releasing many of JavaScript’s subtleties, much like the Café Allongé beloved by coffee enthusiasts everywhere.

how the book is organized

JavaScript Allongé introduces new aspects of programming with functions in each chapter, explaining exactly how JavaScript works. Code examples within each chapter are small and emphasize exposition rather than serving as patterns for everyday use.

Following each chapter are a series of recipes designed to show the application of the chapters ideas in practical form. While the content of each chapter builds naturally on what was discussed in the previous chapter, the recipes may draw upon any aspect of the JavaScript programming language.

A Personal Word About The Recipes

As noted, JavaScript Allongé alternates between chapters describing the semantics of JavaScript’s functions with chapters containing recipes for writing programs with functions. You can read the book in order or read the chapters explaining JavaScript first and return to the recipes later.

The recipes share a common theme: They hail from a style of programming inspired by the creation of small functions that compose with each other. Using these recipes, you’ll learn when it’s appropriate to write:

1 return mapWith ( maybe ( getWith ( 'name' )))( customerList );

Instead of:

1 return customerList . map ( function ( customer ) { 2 if ( customer ) { 3 return customer . name 4 } 5 });

As well as how it works and how to refactor it when you need. This style of programming is hardly the most common thing anyone does in JavaScript, so the argument can be made that more “practical” or “commonplace” recipes would be helpful. If you never read any other books about JavaScript, if you avoid blog posts and screen casts about JavaScript, if you don’t attend workshops or talks about JavaScript, then I agree that this is not One Book to Rule Them All.

But given that there are other resources out there, and that programmers are curious creatures with an unslakable thirst for personal growth, we choose to provide recipes that you are unlikely to find anywhere else in anything like this concentration. The recipes reinforce the lessons taught in the book about functions in JavaScript.

You’ll find all of the recipes collected online at http://allong.es. They’re free to share under the MIT license.

Reginald Braithwaite

reg@braythwayt.com

@raganwald

Legend

Some text in monospaced type like this in the text represents some code being discussed. Some monospaced code in its own lines also represents code being discussed:

1 this . async = do ( async = undefined ) -> 2 3 async = ( fn ) -> 4 ( argv ..., callback ) -> 5 callback ( fn . apply ( this , argv ))

Sometimes it will contain some code for you to type in for yourself. When it does, the result of typing something in will often be shown using //=> , like this:

1 2 + 2 2 //=> 4

A paragraph marked like this is a “key fact.” It summarizes an idea without adding anything new.

A paragraph marked like this is a suggested exercise to be performed on your own.

A paragraph marked like this is an aside. It can be safely ignored. It contains whimsey and other doupleplusunserious logorrhea that will not be on the test.

JavaScript Allongé, the “Six” Edition

This is the original version of JavaScript Allongé. It was written for ECMAScript-5. The overarching theme of the book and approach to programming is as valid today as it was when ECMAScript-5 was the standard for JavaScript, however the details of how best to implement these ideas have changed.

For example, in ECMAScript-5, we write:

1 function maybe ( fn ) { 2 return function () { 3 var i ; 4 5 if ( arguments . length === 0 ) { 6 return 7 } 8 else { 9 for ( i = 0 ; i < arguments . length ; ++ i ) { 10 if ( arguments [ i ] == null ) return 11 } 12 return fn . apply ( this , arguments ) 13 } 14 } 15 }

But in ECMAScript-2015, we write:

1 const maybe = ( fn ) => 2 function (... args ) { 3 if ( args . length === 0 ) { 4 return 5 } 6 else { 7 for ( let arg in args ) { 8 if ( arg == null ) return ; 9 } 10 return fn . apply ( this , args ) 11 } 12 }

Other changes include the introduction of the class keyword, which leads to a greater interest in working with objects, prototypes, and functions.

For this reason, this original manuscript has been retired, and a substantially updated edition, JavaScript Allongé, the “Six” Edition has been written. Please enjoy this copy, but be sure to read the latest edition.

Prelude: Values and Expressions

The following material is extremely basic, however like most stories, the best way to begin is to start at the very beginning.

Imagine we are visiting our favourite coffee shop. They will make for you just about any drink you desire, from a short, intense espresso ristretto through a dry cappuccino, up to those coffee-flavoured desert concoctions featuring various concentrated syrups and milks. (You tolerate the existence of sugary drinks because they provide a sufficient profit margin to the establishment to finance your hanging out there all day using their WiFi and ordering a $3 drink every few hours.)

You express your order at one end of their counter, the folks behind the counter perform their magic, and deliver the coffee you value at the other end. This is exactly how the JavaScript environment works for the purpose of this book. We are going to dispense with web servers, browsers and other complexities and deal with this simple model: You give the computer an expression, and it returns a value, just as you express your wishes to a barista and receive a coffee in return.

values and expressions

All values are expressions. Say you hand the barista a café Cubano. Yup, you hand over a cup with some coffee infused through partially caramelized sugar. You say, “I want one of these.” The barista is no fool, she gives it straight back to you, and you get exactly what you want. Thus, a café Cubano is an expression (you can use it to place an order) and a value (you get it back from the barista).

Let’s try this with something the computer understands easily:

1 42

Is this an expression? A value? Neither? Or both?

The answer is, this is both an expression and a value.1 The way you can tell that it’s both is very easy: When you type it into JavaScript, you get the same thing back, just like our café Cubano:

1 42 2 //=> 42

All values are expressions. That’s easy! Are there any other kinds of expressions? Sure! let’s go back to the coffee shop. Instead of handing over the finished coffee, we can hand over the ingredients. Let’s hand over some ground coffee plus some boiling water.

Astute readers will realize we’re omitting something. Congratulations! Take a sip of espresso. We’ll get to that in a moment.

Now the barista gives us back an espresso. And if we hand over the espresso, we get the espresso right back. So, boiling water plus ground coffee is an expression, but it isn’t a value.2 Boiling water is a value. Ground coffee is a value. Espresso is a value. Boiling water plus ground coffee is an expression.

Let’s try this as well with something else the computer understands easily:

1 "JavaScript" + " " + "Allonge" 2 //=> "JavaScript Allonge"

Now we see that “strings” are values, and you can make an expression out of strings and an operator + . Since strings are values, they are also expressions by themselves. But strings with operators are not values, they are expressions. Now we know what was missing with our “coffee grounds plus hot water” example. The coffee grounds were a value, the boiling hot water was a value, and the “plus” operator between them made the whole thing an expression that was not a value.

values and identity

In JavaScript, we test whether two values are identical with the === operator, and whether they are not identical with the !== operator:

1 2 === 2 2 //=> true 3 4 'hello' !== 'goodbye' 5 //=> true

How does === work, exactly? Imagine that you’re shown a cup of coffee. And then you’re shown another cup of coffee. Are the two cups “identical?” In JavaScript, there are four possibilities:

First, sometimes, the cups are of different kinds. One is a demitasse, the other a mug. This corresponds to comparing two things in JavaScript that have different types. For example, the string "2" is not the same thing as the number 2 . Strings and numbers are different types, so strings and numbers are never identical:

1 2 === '2' 2 //=> false 3 4 true !== 'true' 5 //=> true

Second, sometimes, the cups are of the same type–perhaps two espresso cups–but they have different contents. One holds a single, one a double. This corresponds to comparing two JavaScript values that have the same type but different “content.” For example, the number 5 is not the same thing as the number 2 .

1 true === false 2 //=> false 3 4 2 !== 5 5 //=> true 6 7 'two' === 'five' 8 //=> false

What if the cups are of the same type and the contents are the same? Well, JavaScript’s third and fourth possibilities cover that.

value types

Third, some types of cups have no distinguishing marks on them. If they are the same kind of cup, and they hold the same contents, we have no way to tell the difference between them. This is the case with the strings, numbers, and booleans we have seen so far.

1 2 + 2 === 4 2 //=> true 3 4 ( 2 + 2 === 4 ) === ( 2 !== 5 ) 5 //=> true

Note well what is happening with these examples: Even when we obtain a string, number, or boolean as the result of evaluating an expression, it is identical to another value of the same type with the same “content.” Strings, numbers, and booleans are examples of what JavaScript calls “value” or “primitive” types. We’ll use both terms interchangeably.

We haven’t encountered the fourth possibility yet. Stretching the metaphor somewhat, some types of cups have a serial number on the bottom. So even if you have two cups of the same type, and their contents are the same, you can still distinguish between them.

Cafe Macchiato is also a fine drink, especially when following up on the fortunes of the Azzurri or the standings in the Giro D’Italia

reference types

So what kinds of values might be the same type and have the same contents, but not be considered identical to JavaScript? Let’s meet a data structure that is very common in contemporary programming languages, the Array (other languages sometimes call it a List or a Vector).

An array looks like this: [1, 2, 3] . This is an expression, and you can combine [] with other expressions. Go wild with things like:

1 [ 2 - 1 , 2 , 2 + 1 ] 2 [ 1 , 1 + 1 , 1 + 1 + 1 ]

Notice that you are always generating arrays with the same contents. But are they identical the same way that every value of 42 is identical to every other value of 42 ? Try these for yourself:

1 [ 2 - 1 , 2 , 2 + 1 ] === [ 1 , 2 , 3 ] 2 [ 1 , 2 , 3 ] === [ 1 , 2 , 3 ] 3 [ 1 , 2 , 3 ] === [ 1 , 2 , 3 ]

How about that! When you type [1, 2, 3] or any of its variations, you are typing an expression that generates its own unique array that is not identical to any other array, even if that other array also looks like [1, 2, 3] . It’s as if JavaScript is generating new cups of coffee with serial numbers on the bottom.

Arrays look exceedingly simple, but this word “reference” is so laden with possibilities that there’s an entire chapter devoted to discussing rebinding and references. Try typing this code out: 1 var ouroboros = []; 2 ouroboros [ 0 ] = ouroboros ; 3 //=> [ [Circular] ] You’ve just created an ouroborian array, an array that contains itself.

They look the same, but if you examine them with === , you see that they are different. Every time you evaluate an expression (including typing something in) to create an array, you’re creating a new, distinct value even if it appears to be the same as some other array value. As we’ll see, this is true of many other kinds of values, including functions, the main subject of this book.

1. The first sip: Basic Functions

The perfect Café Allongé begins with the right beans, properly roasted. JavaScript Allongé begins with functions, properly dissected.

As Little As Possible About Functions, But No Less

In JavaScript, functions are values, but they are also much more than simple numbers, strings, or even complex data structures like trees or maps. Functions represent computations to be performed. Like numbers, strings, and arrays, they have a representation. Let’s start with the very simplest possible function. In JavaScript, it looks like this:

1 function () {}

This is a function that is applied to no values and produces no value. How do we represent “no value” in JavaScript? We’ll find out in a minute. First, let’s verify that our function is a value:

1 ( function () {}) 2 //=> [Function]

What!? Why didn’t it type back function () {} for us? This seems to break our rule that if an expression is also a value, JavaScript will give the same value back to us. What’s going on? The simplest and easiest answer is that although the JavaScript interpreter does indeed return that value, displaying it on the screen is a slightly different matter. [Function] is a choice made by the people who wrote Node.js, the JavaScript environment that hosts the JavaScript REPL. If you try the same thing in a browser, you’ll see the code you typed.

I’d prefer something else, but I must accept that what gets typed back to us on the screen is arbitrary, and all that really counts is that it is somewhat useful for a human to read. But we must understand that whether we see [Function] or function () {} , internally JavaScript has a full and proper function.

functions and identities

You recall that we have two types of values with respect to identity: Value types and reference types. Value types share the same identity if they have the same contents.Reference types do not.

Which kind are functions? Let’s try it. For reasons of appeasing the JavaScript parser, we’ll enclose our functions in parentheses:

1 ( function () {}) === ( function () {}) 2 //=> false

Like arrays, every time you evaluate an expression to produce a function, you get a new function that is not identical to any other function, even if you use the same expression to generate it. “Function” is a reference type.

applying functions

Let’s put functions to work. The way we use functions is to apply them to zero or more values called arguments. Just as 2 + 2 produces a value (in this case 4 ), applying a function to zero or more arguments produces a value as well.

Here’s how we apply a function to some values in JavaScript: Let’s say that fn_expr is an expression that when evaluated, produces a function. Let’s call the arguments args. Here’s how to apply a function to some arguments:

fn_expr ( args )

Right now, we only know about one such expression: function () {} , so let’s use it. We’ll put it in parentheses1 to keep the parser happy, like we did above: (function () {}) . Since we aren’t giving it any arguments, we’ll simply write () after the expression. So we write:

1 ( function () {})() 2 //=> undefined

What is this undefined ?

undefined

In JavaScript, the absence of a value is written undefined , and it means there is no value. It will crop up again. undefined is its own type of value, and it acts like a value type:

1 undefined 2 //=> undefined

Like numbers, booleans and strings, JavaScript can print out the value undefined .

1 undefined === undefined 2 //=> true 3 ( function () {})() === ( function () {})() 4 //=> true 5 ( function () {})() === undefined 6 //=> true

No matter how you evaluate undefined , you get an identical value back. undefined is a value that means “I don’t have a value.” But it’s still a value :-)

You might think that undefined in JavaScript is equivalent to NULL in SQL. No. In SQL, two things that are NULL are not equal to nor share the same identity, because two unknowns can’t be equal. In JavaScript, every undefined is identical to every other undefined .

void

We’ve seen that JavaScript represents an undefined value by typing undefined , and we’ve generated undefined values in two ways:

By evaluating a function that doesn’t return a value (function () {})() , and; By writing undefined ourselves.

There’s a third way, with JavaScript’s void operator. Behold:

1 void 0 2 //=> undefined 3 void 1 4 //=> undefined 5 void ( 2 + 2 ) 6 //=> undefined

void is an operator that takes any value and evaluates to undefined , always. So, when we deliberately want an undefined value, should we use the first, second, or third form?2 The answer is, use void . By convention, use void 0 .

The first form works but it’s cumbersome. The second form works most of the time, but it is possible to break it by reassigning undefined to a different value, something we’ll discuss in Reassignment and Mutation. The third form is guaranteed to always work, so that’s what we will use.3

functions with no arguments and their bodies

Back to our function. We evaluated this:

1 ( function () {})() 2 //=> undefined

Let’s recall that we were applying the function function () {} to no arguments (because there was nothing inside of () ). So how do we know to expect undefined ? That’s easy:

When we define a function4, we write the word function . We then put a (possibly empty) list of arguments, then we give the function a body that is enclosed in braces {...} . Function bodies are (possibly empty) lists of JavaScript statements separated by semicolons.

Something like: { statement1; statement2; statement3; … ; statementn }

We haven’t discussed these statements. What’s a statement?

There are many kinds of JavaScript statements, but the first kind is one we’ve already met. An expression is a JavaScript statement. Although they aren’t very practical, the following are all valid JavaScript functions, and they all evaluate to undefined when applied:

1 ( function () { 2 + 2 }) 2 3 ( function () { 1 + 1 ; 2 + 2 })

You can also separate statements with line breaks.5 The convention is to use some form of consistent indenting:

1 ( function () { 2 1 + 1 ; 3 2 + 2 4 }) 5 6 ( function () { 7 ( function () { 8 ( function () { 9 ( function () { 10 }) 11 }) 12 }); 13 ( function () { 14 }) 15 })

That last one’s a doozy, but since a function body can contain a statement, and a statement can be an expression, and a function is an expression…. You get the idea.

So how do we get a function to return a value when applied? With the return keyword and any expression:

1 ( function () { return 0 })() 2 //=> 0 3 4 ( function () { return 1 })() 5 //=> 1 6 7 ( function () { return 'Hello ' + 'World' })() 8 // 'Hello World'

The return keyword creates a return statement that immediately terminates the function application and returns the result of evaluating its expression.

functions that evaluate to functions

If an expression that evaluates to a function is, well, an expression, and if a return statement can have any expression on its right side… Can we put an expression that evaluates to a function on the right side of a function expression?

Yes:

1 function () { 2 return ( function () {}) 3 }

That’s a function! It’s a function that when applied, evaluates to a function that when applied, evaluates to undefined .6 Let’s use a simpler terminology. Instead of saying “that when applied, evaluates to _____,” we will say “gives _____.” And instead of saying “gives undefined,” we’ll say “doesn’t give anything.”

So we have a function, that gives a function, that doesn’t give anything. Likewise:

1 function () { 2 return ( function () { 3 return true 4 }) 5 }

That’s a function, that gives a function, that gives true :

1 ( function () { 2 return ( function () { 3 return true 4 }) 5 })()() 6 //=> true

Well. We’ve been very clever, but so far this all seems very abstract. Diffraction of a crystal is beautiful and interesting in its own right, but you can’t blame us for wanting to be shown a practical use for it, like being able to determine the composition of a star millions of light years away. So… In the next chapter, “I’d Like to Have an Argument, Please,” we’ll see how to make functions practical.

Ah. I’d Like to Have an Argument, Please.

Up to now, we’ve looked at functions without arguments. We haven’t even said what an argument is, only that our functions don’t have any.

Most programmers are perfectly familiar with arguments (often called “parameters”). Secondary school mathematics discusses this. So you know what they are, and I know that you know what they are, but please be patient with the explanation!

Let’s make a function with an argument:

1 function ( room ) {}

This function has one argument, room , and no body. Here’s a function with two arguments and no body:

1 function ( room , board ) {}

I’m sure you are perfectly comfortable with the idea that this function has two arguments, room , and board . What does one do with the arguments? Use them in the body, of course. What do you think this is?

1 function ( diameter ) { return diameter * 3.14159265 }

It’s a function for calculating the circumference of a circle given the diameter. I read that aloud as “When applied to a value representing the diameter, this function returns the diameter times 3.14159265.”

Remember that to apply a function with no arguments, we wrote (function () {})() . To apply a function with an argument (or arguments), we put the argument (or arguments) within the parentheses, like this:

1 ( function ( diameter ) { return diameter * 3.14159265 })( 2 ) 2 //=> 6.2831853

You won’t be surprised to see how to write and apply a function to two arguments:

1 ( function ( room , board ) { return room + board })( 800 , 150 ) 2 //=> 950

a quick summary of functions and bodies How arguments are used in a body’s expression is probably perfectly obvious to you from the examples, especially if you’ve used any programming language (except for the dialect of BASIC–which I recall from my secondary school–that didn’t allow parameters when you called a procedure). Expressions consist either of representations of values (like 3.14159265 , true , and undefined ), operators that combine expressions (like 3 + 2 ), some special forms like [1, 2, 3] for creating arrays out of expressions, or function ( arguments ) { body-statements } for creating functions. One of the important possible statements is a return statement. A return statement accepts any valid JavaScript expression. This loose definition is recursive, so we can intuit (or use our experience with other languages) that since a function can contain a return statement with an expression, we can write a function that returns a function, or an array that contains another array expression. Or a function that returns an array, an array of functions, a function that returns an array of functions, and so forth: 1 function () { 2 return function () {} 3 } 4 5 function () { 6 return [ 1 , 2 , 3 ] 7 } 8 9 [ 1 , [ 2 , 3 ], 4 ] 10 11 function () { 12 return [ 13 ( function () { return 1 }), 14 ( function () { return 2 }), 15 ( function () { return 3 }) 16 ] 17 }

call by value

Like most contemporary programming languages, JavaScript uses the “call by value” evaluation strategy. That means that when you write some code that appears to apply a function to an expression or expressions, JavaScript evaluates all of those expressions and applies the functions to the resulting value(s).

So when you write:

1 ( function ( diameter ) { return diameter * 3.14159265 })( 1 + 1 ) 2 //=> 6.2831853

What happened internally is that the expression 1 + 1 was evaluated first, resulting in 2 . Then our circumference function was applied to 2 .8

variables and bindings

Right now everything looks simple and straightforward, and we can move on to talk about arguments in more detail. And we’re going to work our way up from function (diameter) { return diameter * 3.14159265 } to functions like:

1 function ( x ) { return ( function ( y ) { return x }) }

function (x) { return (function (y) { return x }) } just looks crazy, as if we are learning English as a second language and the teacher promises us that soon we will be using words like antidisestablishmentarianism. Besides a desire to use long words to sound impressive, this is not going to seem attractive until we find ourselves wanting to discuss the role of the Church of England in 19th century British politics. But there’s another reason for learning the word antidisestablishmentarianism: We might learn how prefixes and postfixes work in English grammar. It’s the same thing with function (x) { return (function (y) { return x }) } . It has a certain important meaning in its own right, and it’s also an excellent excuse to learn about functions that make functions, environments, variables, and more.

In order to talk about how this works, we should agree on a few terms (you may already know them, but let’s check-in together and “synchronize our dictionaries”). The first x , the one in function (x) ... , is an argument. The y in function (y) ... is another argument. The second x , the one in { return x } , is not an argument, it’s an expression referring to a variable. Arguments and variables work the same way whether we’re talking about function (x) { return (function (y) { return x }) } or just plain function (x) { return x } .

Every time a function is invoked (“invoked” means “applied to zero or more arguments”), a new environment is created. An environment is a (possibly empty) dictionary that maps variables to values by name. The x in the expression that we call a “variable” is itself an expression that is evaluated by looking up the value in the environment.

How does the value get put in the environment? Well for arguments, that is very simple. When you apply the function to the arguments, an entry is placed in the dictionary for each argument. So when we write:

1 ( function ( x ) { return x })( 2 ) 2 //=> 2

What happens is this:

JavaScript parses this whole thing as an expression made up of several sub-expressions. It then starts evaluating the expression, including evaluating sub-expressions One sub-expression, function (x) { return x } evaluates to a function. Another, 2 , evaluates to the number 2. JavaScript now evaluates applying the function to the argument 2 . Here’s where it gets interesting… An environment is created. The value ‘2’ is bound to the name ‘x’ in the environment. The expression ‘x’ (the right side of the function) is evaluated within the environment we just created. The value of a variable when evaluated in an environment is the value bound to the variable’s name in that environment, which is ‘2’ And that’s our result.

When we talk about environments, we’ll use an unsurprising syntax for showing their bindings: {x: 2, ...} . meaning, that the environment is a dictionary, and that the value 2 is bound to the name x , and that there might be other stuff in that dictionary we aren’t discussing right now.

call by sharing

Earlier, we distinguished JavaScript’s value types from its reference types. At that time, we looked at how JavaScript distinguishes objects that are identical from objects that are not. Now it is time to take another look at the distinction between value and reference types.

There is a property that JavaScript strictly maintains: When a value–any value–is passed as an argument to a function, the value bound in the function’s environment must be identical to the original.

We said that JavaScript binds names to values, but we didn’t say what it means to bind a name to a value. Now we can elaborate: When JavaScript binds a value-type to a name, it makes a copy of the value and places the copy in the environment. As you recall, value types like strings and numbers are identical to each other if they have the same content. So JavaScript can make as many copies of strings, numbers, or booleans as it wishes.

What about reference types? JavaScript does not place copies of reference values in any environment. JavaScript places references to reference types in environments, and when the value needs to be used, JavaScript uses the reference to obtain the original.

Because many references can share the same value, and because JavaScript passes references as arguments, JavaScript can be said to implement “call by sharing” semantics. Call by sharing is generally understood to be a specialization of call by value, and it explains why some values are known as value types and other values are known as reference types.

And with that, we’re ready to look at closures. When we combine our knowledge of value types, reference types, arguments, and closures, we’ll understand why this function always evaluates to true no matter what argument9 you apply it to:

1 function ( value ) { 2 return ( function ( copy ) { 3 return copy === value 4 })( value ) 5 }

Closures and Scope

It’s time to see how a function within a function works:

1 ( function ( x ) { 2 return function ( y ) { 3 return x 4 } 5 })( 1 )( 2 ) 6 //=> 1

First off, let’s use what we learned above. Given ( some function )( some argument ) , we know that we apply the function to the argument, create an environment, bind the value of the argument to the name, and evaluate the function’s expression. So we do that first with this code:

1 ( function ( x ) { 2 return function ( y ) { 3 return x 4 } 5 })( 1 ) 6 //=> [Function]

The environment belonging to the function with signature function (x) ... becomes {x: 1, ...} , and the result of applying the function is another function value. It makes sense that the result value is a function, because the expression for function (x) ... ’s body is:

1 function ( y ) { 2 return x 3 }

So now we have a value representing that function. Then we’re going to take the value of that function and apply it to the argument 2 , something like this:

1 ( function ( y ) { 2 return x 3 })( 2 )

So we seem to get a new environment {y: 2, ...} . How is the expression x going to be evaluated in that function’s environment? There is no x in its environment, it must come from somewhere else.

This, by the way, is one of the great defining characteristics of JavaScript and languages in the same family: Whether they allow things like functions to nest inside each other, and if so, how they handle variables from “outside” of a function that are referenced inside a function. For example, here’s the equivalent code in Ruby: 1 lambda { | x | 2 lambda { | y | x } 3 } [ 1 ][ 2 ] 4 #=> 1 Now let’s enjoy a relaxed Allongé before we continue!

If functions without free variables are pure, are closures impure?

The function function (y) { return x } is interesting. It contains a free variable, x .10 A free variable is one that is not bound within the function. Up to now, we’ve only seen one way to “bind” a variable, namely by passing in an argument with the same name. Since the function function (y) { return x } doesn’t have an argument named x , the variable x isn’t bound in this function, which makes it “free.”

Now that we know that variables used in a function are either bound or free, we can bifurcate functions into those with free variables and those without:

Functions containing no free variables are called pure functions.

Functions containing one or more free variables are called closures.

Pure functions are easiest to understand. They always mean the same thing wherever you use them. Here are some pure functions we’ve already seen:

1 function () {} 2 3 function ( x ) { 4 return x 5 } 6 7 function ( x ) { 8 return function ( y ) { 9 return x 10 } 11 }

The first function doesn’t have any variables, therefore doesn’t have any free variables. The second doesn’t have any free variables, because its only variable is bound. The third one is actually two functions, one inside the other. function (y) ... has a free variable, but the entire expression refers to function (x) ... , and it doesn’t have a free variable: The only variable anywhere in its body is x , which is certainly bound within function (x) ... .

From this, we learn something: A pure function can contain a closure.

If pure functions can contain closures, can a closure contain a pure function? Using only what we’ve learned so far, attempt to compose a closure that contains a pure function. If you can’t, give your reasoning for why it’s impossible.

Pure functions always mean the same thing because all of their “inputs” are fully defined by their arguments. Not so with a closure. If I present to you this pure function function (x, y) { return x + y } , we know exactly what it does with (2, 2) . But what about this closure: function (y) { return x + y } ? We can’t say what it will do with argument (2) without understanding the magic for evaluating the free variable x .

it’s always the environment

To understand how closures are evaluated, we need to revisit environments. As we’ve said before, all functions are associated with an environment. We also hand-waved something when describing our environment. Remember that we said the environment for (function (x) { return (function (y) { return x }) })(1) is {x: 1, ...} and that the environment for (function (y) { return x })(2) is {y: 2, ...} ? Let’s fill in the blanks!

The environment for (function (y) { return x })(2) is actually {y: 2, '..': {x: 1, ...}} . '..' means something like “parent” or “enclosure” or “super-environment.” It’s function (x) ... ’s environment, because the function function (y) { return x } is within function (x) ... ’s body. So whenever a function is applied to arguments, its environment always has a reference to its parent environment.

And now you can guess how we evaluate (function (y) { return x })(2) in the environment {y: 2, '..': {x: 1, ...}} . The variable x isn’t in function (y) ... ’s immediate environment, but it is in its parent’s environment, so it evaluates to 1 and that’s what (function (y) { return x })(2) returns even though it ended up ignoring its own argument.

function (x) { return x } is called the I Combinator or Identity Function. function (x) { return (function (y) { return x }) } is called the K Combinator or Kestrel. Some people get so excited by this that they write entire books about them, some are great, some–how shall I put this–are interesting if you use Ruby.

Functions can have grandparents too:

1 function ( x ) { 2 return function ( y ) { 3 return function ( z ) { 4 return x + y + z 5 } 6 } 7 }

This function does much the same thing as:

1 function ( x , y , z ) { 2 return x + y + z 3 }

Only you call it with (1)(2)(3) instead of (1, 2, 3) . The other big difference is that you can call it with (1) and get a function back that you can later call with (2)(3) .

The first function is the result of currying the second function. Calling a curried function with only some of its arguments is sometimes called partial application. Some programming languages automatically curry and partially evaluate functions without the need to manually nest them.

shadowy variables from a shadowy planet

An interesting thing happens when a variable has the same name as an ancestor environment’s variable. Consider:

1 function ( x ) { 2 return function ( x , y ) { 3 return x + y 4 } 5 }

The function function (x, y) { return x + y } is a pure function, because its x is defined within its own environment. Although its parent also defines an x , it is ignored when evaluating x + y . JavaScript always searches for a binding starting with the functions own environment and then each parent in turn until it finds one. The same is true of:

1 function ( x ) { 2 return function ( x , y ) { 3 return function ( w , z ) { 4 return function ( w ) { 5 return x + y + z 6 } 7 } 8 } 9 }

When evaluating x + y + z , JavaScript will find x and y in the great-grandparent scope and z in the parent scope. The x in the great-great-grandparent scope is ignored, as are both w s. When a variable has the same name as an ancestor environment’s binding, it is said to shadow the ancestor.

This is often a good thing.

which came first, the chicken or the egg?

This behaviour of pure functions and closures has many, many consequences that can be exploited to write software. We are going to explore them in some detail as well as look at some of the other mechanisms JavaScript provides for working with variables and mutable state.

But before we do so, there’s one final question: Where does the ancestry start? If there’s no other code in a file, what is function (x) { return x } ’s parent environment?

JavaScript always has the notion of at least one environment we do not control: A global environment in which many useful things are bound such as libraries full of standard functions. So when you invoke (function (x) { return x })(1) in the REPL, its full environment is going to look like this: {x: 1, '..': global environment } .

Sometimes, programmers wish to avoid this. If you don’t want your code to operate directly within the global environment, what can you do? Create an environment for them, of course. Many programmers choose to write every JavaScript file like this:

1 // top of the file 2 ( function () { 3 4 // ... lots of JavaScript ... 5 6 })(); 7 // bottom of the file

The effect is to insert a new, empty environment in between the global environment and your own functions: {x: 1, '..': {'..': global environment }} . As we’ll see when we discuss mutable state, this helps to prevent programmers from accidentally changing the global state that is shared by code in every file when they use the var keyword properly.

Let’s Talk Var

Up to now, all we’ve really seen are anonymous functions, functions that don’t have a name. This feels very different from programming in most other languages, where the focus is on naming functions, methods, and procedures. Naming things is a critical part of programming, but all we’ve seen so far is how to name arguments.

There are other ways to name things in JavaScript, but before we learn some of those, let’s see how to use what we already have to name things. Let’s revisit a very simple example:

1 function ( diameter ) { 2 return diameter * 3.14159265 3 }

What is this “3.14159265” number? Pi, obviously. We’d like to name it so that we can write something like:

1 function ( diameter ) { 2 return diameter * Pi 3 }

In order to bind 3.14159265 to the name Pi , we’ll need a function with a parameter of Pi applied to an argument of 3.14159265 . If we put our function expression in parentheses, we can apply it to the argument of 3.14159265 :

1 ( function ( Pi ) { 2 return ???? 3 })( 3.14159265 )

What do we put inside our new function that binds 3.14159265 to the name Pi when evaluated? Our circumference function, of course:

1 ( function ( Pi ) { 2 return function ( diameter ) { 3 return diameter * Pi 4 } 5 })( 3.14159265 )

This expression, when evaluated, returns a function that calculates circumferences. It differs from our original in that it names the constant Pi . Let’s test it:

1 ( function ( Pi ) { 2 return function ( diameter ) { 3 return diameter * Pi 4 } 5 })( 3.14159265 )( 2 ) 6 //=> 6.2831853

That works! We can bind anything we want in an expression by wrapping it in a function that is immediately invoked with the value we want to bind.

immediately invoked function expressions

JavaScript programmers regularly use the idea of writing an expression that denotes a function and then immediately applying it to arguments. Explaining the pattern, Ben Alman coined the term Immediately Invoked Function Expression for it, often abbreviated “IIFE.” As we’ll see in a moment, an IIFE need not have parameters:

1 ( function () { 2 // ... do something here... 3 })();

When an IIFE binds values to names (as we did above with Pi ), retro-grouch programmers often call it “let.”11 And confusing the issue, upcoming versions of JavaScript have support for a let keyword that has a similar binding behaviour.

var

Using an IIFE to bind names works very well, but only a masochist would write programs this way in JavaScript. Besides all the extra characters, it suffers from a fundamental semantic problem: there is a big visual distance between the name Pi and the value 3.14159265 we bind to it. They should be closer. Is there another way?

Yes.

Another way to write our “circumference” function would be to pass Pi along with the diameter argument, something like this:

1 function ( diameter , Pi ) { 2 return diameter * Pi 3 }

And you could use it like this:

1 ( function ( diameter , Pi ) { 2 return diameter * Pi 3 })( 2 , 3.14159265 ) 4 //=> 6.2831853

This differs from our example above in that there is only one environment, rather than two. We have one binding in the environment representing our regular argument, and another our “constant.” That’s more efficient, and it’s almost what we wanted all along: A way to bind 3.14159265 to a readable name.

JavaScript gives us a way to do that, the var keyword. We’ll learn a lot more about var in future chapters, but here’s the most important thing you can do with var :

1 function ( diameter ) { 2 var Pi = 3.14159265 ; 3 4 return diameter * Pi 5 }

The var keyword introduces one or more bindings in the current function’s environment. It works just as we want:

1 ( function ( diameter ) { 2 var Pi = 3.14159265 ; 3 4 return diameter * Pi 5 })( 2 ) 6 //=> 6.2831853

You can bind any expression. Functions are expressions, so you can bind helper functions:

1 function ( d ) { 2 var calc = function ( diameter ) { 3 var Pi = 3.14159265 ; 4 5 return diameter * Pi 6 }; 7 8 return "The circumference is " + calc ( d ) 9 }

Notice calc(d) ? This underscores what we’ve said: if you have an expression that evaluates to a function, you apply it with () . A name that’s bound to a function is a valid expression evaluating to a function.12

Amazing how such an important idea–naming functions–can be explained en passant in just a few words. That emphasizes one of the things JavaScript gets really, really right: Functions as “first class entities.” Functions are values that can be bound to names like any other value, passed as arguments, returned from other functions, and so forth.

You can bind more than one name-value pair by separating them with commas. For readability, most people put one binding per line:

1 function ( d ) { 2 var Pi = 3.14159265 , 3 calc = function ( diameter ) { 4 return diameter * Pi 5 }; 6 7 return "The circumference is " + calc ( d ) 8 }

These examples use the var keyword to bind names in the same environment as our function. We can also create a new scope using an IIFE if we wish to bind some names in part of a function:

1 function foobar () { 2 3 // do something without foo or bar 4 5 ( function () { 6 var foo = 'foo' , 7 bar = 'bar' ; 8 9 // ... do something with foo and bar ... 10 11 })(); 12 13 // do something else without foo or bar 14 15 }

Naming Functions

Let’s get right to it. This code does not name a function:

1 var repeat = function ( str ) { 2 return str + str 3 };

It doesn’t name the function “repeat” for the same reason that var answer = 42 doesn’t name the number 42 . That snippet of code binds an anonymous function to a name in an environment, but the function itself remains anonymous.

JavaScript does have a syntax for naming a function, it looks like this:

1 var bindingName = function actualName () { 2 //... 3 };

In this expression, bindingName is the name in the environment, but actualName is the function’s actual name. This is a named function expression. That may seem confusing, but think of the binding names as properties of the environment, not the function itself. And indeed the name is a property:

1 bindingName . name 2 //=> 'actualName'

In this book we are not examining JavaScript’s tooling such as debuggers baked into browsers, but we will note that when you are navigating call stacks in all modern tools, the function’s binding name is ignored but its actual name is displayed, so naming functions is very useful even if they don’t get a formal binding, e.g.

1 someBackboneView . on ( 'click' , function clickHandler () { 2 //... 3 });

Now, the function’s actual name has no effect on the environment in which it is used. To whit:

1 var bindingName = function actualName () { 2 //... 3 }; 4 5 bindingName 6 //=> [Function: actualName] 7 8 actualName 9 //=> ReferenceError: actualName is not defined

So “actualName” isn’t bound in the environment where we use the named function expression. Is it bound anywhere else? Yes it is:

1 var fn = function even ( n ) { 2 if ( n === 0 ) { 3 return true 4 } 5 else return ! even ( n - 1 ) 6 } 7 8 fn ( 5 ) 9 //=> false 10 11 fn ( 2 ) 12 //=> true

even is bound within the function itself, but not outside it. This is useful for making recursive functions.

function declarations

We’ve actually buried the lede.13 Naming functions for the purpose of debugging is not as important as what we’re about to discuss. There is another syntax for naming and/or defining a function. It’s called a function declaration, and it looks like this:

1 function someName () { 2 // ... 3 }

This behaves a little like:

1 var someName = function someName () { 2 // ... 3 }

In that it binds a name in the environment to a named function. However, consider this piece of code:

1 ( function () { 2 return someName ; 3 4 var someName = function someName () { 5 // ... 6 } 7 })() 8 //=> undefined

This is what we expect given what we learned about var: Although someName is declared later in the function, JavaScript behaves as if you’d written:

1 ( function () { 2 var someName ; 3 4 return someName ; 5 6 someName = function someName () { 7 // ... 8 } 9 })()

What about a function declaration without var ?

1 ( function () { 2 return someName ; 3 4 function someName () { 5 // ... 6 } 7 })() 8 //=> [Function: someName]

Aha! It works differently, as if you’d written:

1 ( function () { 2 var someName = function someName () { 3 // ... 4 } 5 return someName ; 6 })()

That difference is intentional on the part of JavaScript’s design to facilitate a certain style of programming where you put the main logic up front, and the “helper functions” at the bottom. It is not necessary to declare functions in this way in JavaScript, but understanding the syntax and its behaviour (especially the way it differs from var ) is essential for working with production code.

function declaration caveats14

Function declarations are formally only supposed to be made at what we might call the “top level” of a function. Although some JavaScript environments may permit it, this example is technically illegal and definitely a bad idea:

1 // function declarations should not happen inside of 2 // a block and/or be conditionally executed 3 if ( frobbishes . arePizzled ()) { 4 function complainToFactory () { 5 // ... 6 } 7 }

The big trouble with expressions like this is that they may work just fine in your test environment but work a different way in production. Or it may work one way today and a different way when the JavaScript engine is updated, say with a new optimization.

Another caveat is that a function declaration cannot exist inside of any expression, otherwise it’s a function expression. So this is a function declaration:

1 function trueDat () { return true }

But this is not:

1 ( function trueDat () { return true })

The parentheses make this an expression.

Combinators and Function Decorators

higher-order functions

As we’ve seen, JavaScript functions take values as arguments and return values. JavaScript functions are values, so JavaScript functions can take functions as arguments, return functions, or both. Generally speaking, a function that either takes functions as arguments or returns a function (or both) is referred to as a “higher-order” function.

Here’s a very simple higher-order function that takes a function as an argument:

1 function repeat ( num , fn ) { 2 var i , value ; 3 4 for ( i = 1 ; i <= num ; ++ i ) 5 value = fn ( i ); 6 7 return value ; 8 } 9 10 repeat ( 3 , function () { 11 console . log ( 'Hello' ) 12 }) 13 //=> 14 'Hello' 15 'Hello' 16 'Hello' 17 undefined

Higher-order functions dominate JavaScript Allongé. But before we go on, we’ll talk about some specific types of higher-order functions.

combinators

The word “combinator” has a precise technical meaning in mathematics:

“A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.”–Wikipedia

If we were learning Combinatorial Logic, we’d start with the most basic combinators like S , K , and I , and work up from there to practical combinators. We’d learn that the fundamental combinators are named after birds following the example of Raymond Smullyan’s famous book To Mock a Mockingbird.

In this book, we will be using a looser definition of “combinator:” Higher-order pure functions that take only functions as arguments and return a function. We won’t be strict about using only previously defined combinators in their construction.

Let’s start with a useful combinator: Most programmers call it Compose, although the logicians call it the B combinator or “Bluebird.” Here is the typical15 programming implementation:

1 function compose ( a , b ) { 2 return function ( c ) { 3 return a ( b ( c )) 4 } 5 }

Let’s say we have:

1 function addOne ( number ) { 2 return number + 1 3 } 4 5 function doubleOf ( number ) { 6 return number * 2 7 }

With compose , anywhere you would write

1 function doubleOfAddOne ( number ) { 2 return doubleOf ( addOne ( number )) 3 }

You could also write:

1 var doubleOfAddOne = compose ( doubleOf , addOne );

This is, of course, just one example of many. You’ll find lots more perusing the recipes in this book. While some programmers believe “There Should Only Be One Way To Do It,” having combinators available as well as explicitly writing things out with lots of symbols and keywords has some advantages when used judiciously.

a balanced statement about combinators

Code that uses a lot of combinators tends to name the verbs and adverbs (like doubleOf , addOne , and compose ) while avoiding language keywords and the names of nouns (like number ). So one perspective is that combinators are useful when you want to emphasize what you’re doing and how it fits together, and more explicit code is useful when you want to emphasize what you’re working with.

function decorators

A function decorator is a higher-order function that takes one function as an argument, returns another function, and the returned function is a variation of the argument function. Here’s a ridiculous example of a decorator:

1 function not ( fn ) { 2 return function ( argument ) { 3 return ! fn ( argument ) 4 } 5 }

So instead of writing !someFunction(42) , you can write not(someFunction)(42) . Hardly progress. But like for compose , if you have:

1 function something ( x ) { 2 return x != null 3 }

Then you could write either:

1 function nothing ( x ) { 2 return ! something ( x ) 3 }

Or:

1 var nothing = not ( something );

not is a function decorator because it modifies a function while remaining strongly related to the original function’s semantics. You’ll see other function decorators in the recipes, like once, mapWith, and maybe. Function decorators aren’t strict about being pure functions, so there’s more latitude for making decorators than combinators.

Building Blocks

When you look at functions within functions in JavaScript, there’s a bit of a “spaghetti code” look to it. The strength of JavaScript is that you can do anything. The weakness is that you will. There are ifs, fors, returns, everything thrown higgledy piggledy together. Although you needn’t restrict yourself to a small number of simple patterns, it can be helpful to understand the patterns so that you can structure your code around some basic building blocks.

composition

One of the most basic of these building blocks is composition:

1 function cookAndEat ( food ) { 2 return eat ( cook ( food )) 3 }

It’s really that simple: Whenever you are chaining two or more functions together, you’re composing them. You can compose them with explicit JavaScript code as we’ve just done. You can also generalize composition with the B Combinator or “compose” that we saw in Combinators and Decorators:

1 function compose ( a , b ) { 2 return function ( c ) { 3 return a ( b ( c )) 4 } 5 } 6 7 var cookAndEat = compose ( eat , cook );

If that was all there was to it, composition wouldn’t matter much. But like many patterns, using it when it applies is only 20% of the benefit. The other 80% comes from organizing your code such that you can use it: Writing functions that can be composed in various ways.

In the recipes, we’ll look at a decorator called once: It ensures that a function can only be executed once. Thereafter, it does nothing. Once is useful for ensuring that certain side effects are not repeated. We’ll also look at maybe: It ensures that a function does nothing if it is given nothing (like null or undefined ) as an argument.

Of course, you needn’t use combinators to implement either of these ideas, you can use if statements. But once and maybe compose, so you can chain them together as you see fit:

1 function actuallyTransfer ( from , to , amount ) { 2 // do something 3 } 4 5 var invokeTransfer = once ( maybe ( actuallyTransfer (...)));

partial application

Another basic building block is partial application. When a function takes multiple arguments, we “apply” the function to the arguments by evaluating it with all of the arguments, producing a value. But what if we only supply some of the arguments? In that case, we can’t get the final value, but we can get a function that represents part of our application.

Code is easier than words for this. The Underscore library provides a higher-order function called map.16 It applies another function to each element of an array, like this:

1 _ . map ([ 1 , 2 , 3 ], function ( n ) { return n * n }) 2 //=> [1, 4, 9]

This code implements a partial application of the map function by applying the function function (n) { return n * n } as its second argument:

1 function squareAll ( array ) { 2 return _ . map ( array , function ( n ) { return n * n }) 3 }

The resulting function– squareAll –is still the map function, it’s just that we’ve applied one of its two arguments already. squareAll is nice, but why write one function every time we want to partially apply a function to a map? We can abstract this one level higher. mapWith takes any function as an argument and returns a partially applied map function.

1 function mapWith ( fn ) { 2 return function ( array ) { 3 return _ . map ( array , fn ) 4 } 5 } 6 7 var squareAll = mapWith ( function ( n ) { return n * n }); 8 9 squareAll ([ 1 , 2 , 3 ]) 10 //=> [1, 4, 9]

We’ll discuss mapWith again in the recipes. The important thing to see is that partial application is orthogonal to composition, and that they both work together nicely:

1 var safeSquareAll = mapWith ( maybe ( function ( n ) { return n * n })); 2 3 safeSquareAll ([ 1 , null , 2 , 3 ]) 4 //=> [1, null, 4, 9]

We generalized composition with the compose combinator. Partial application also has a combinator, which we’ll see in the partial recipe.

I’d Like to Have Some Arguments. Again.

As we’ve discussed, when a function is applied to arguments (or “called”), JavaScript binds the values of the arguments to the function’s argument names in an environment created for the function’s execution. What we didn’t discuss is that JavaScript also binds some “magic” names in addition to any you put in the argument list.

You should never attempt to define your own bindings against these names. Consider them read-only at all times. The first is called this and it is bound to something called the function’s context. We will explore that when we start discussing objects and classes. The second is very interesting, it’s called arguments , and the most interesting thing about it is that it contains a list of arguments passed to the function:

1 function plus ( a , b ) { 2 return arguments [ 0 ] + arguments [ 1 ] 3 } 4 5 plus ( 2 , 3 ) 6 //=> 5

Although arguments looks like an array, it isn’t an array:17 It’s more like an object18 that happens to bind some values to properties with names that look like integers starting with zero:

1 function args ( a , b ) { 2 return arguments 3 } 4 5 args ( 2 , 3 ) 6 //=> { '0': 2, '1': 3 }

arguments always contains all of the arguments passed to a function, regardless of how many are declared. Therefore, we can write plus like this:

1 function plus () { 2 return arguments [ 0 ] + arguments [ 1 ] 3 } 4 5 plus ( 2 , 3 ) 6 //=> 5

When discussing objects, we’ll discuss properties in more depth. Here’s something interesting about arguments :

1 function howMany () { 2 return arguments [ 'length' ] 3 } 4 5 howMany () 6 //=> 0 7 8 howMany ( 'hello' ) 9 //=> 1 10 11 howMany ( 'sharks' , 'are' , 'apex' , 'predators' ) 12 //=> 4

The most common use of the arguments binding is to build functions that can take a variable number of arguments. We’ll see it used in many of the recipes, starting off with partial application and ellipses.

Summary

Functions Functions are values that can be part of expressions, returned from other functions, and so forth.

Functions are reference values.

Functions are applied to arguments.

The arguments are passed by sharing, which is also called “pass by value.”

Function bodies have zero or more expressions.

Function application evaluates whatever is returned with the return keyword, or to undefined .

keyword, or to . Function application creates a scope. Scopes are nested and free variable references closed over.

Variables can shadow variables in an enclosing scope.

let is an idiom where we create a function and call it immediately in order to bind values to names.

is an idiom where we create a function and call it immediately in order to bind values to names. JavaScript uses var to bind variables within a function’s scope.

2. The Recipe Cheat Sheet

In the recipes, you may see one or more of the following JavaScript constructs being used before being fully explained in the text. Here’re some brief explanations to tide you over:

apply and call

Functions are applied with () . But they also have methods for applying them to arguments. .call and .apply are explained when we discuss function contexts, but here are some examples:

1 function plus ( a , b ) { 2 return a + b 3 } 4 5 plus ( 2 , 3 ) 6 //=> 5 7 8 plus . call ( this , 2 , 3 ) 9 //=> 5 10 11 plus . apply ( this , [ 2 , 3 ]) 12 //=> 5

slice

Arrays have a .slice method. The function can always be found at Array.prototype.slice . It works like this:

1 [ 1 , 2 , 3 , 4 , 5 ]. slice ( 0 ) 2 //=> [1, 2, 3, 4, 5] 3 4 [ 1 , 2 , 3 , 4 , 5 ]. slice ( 1 ) 5 //=> [2, 3, 4, 5] 6 7 [ 1 , 2 , 3 , 4 , 5 ]. slice ( 1 , 4 ) 8 //=> [2, 3, 4]

Note that slice always creates a new array, so .slice(0) makes a copy of an array. The arguments pseudo-variable is not an array, but you can use .slice with it like this to get an array of all or some of the arguments:

1 Array . prototype . slice . call ( arguments , 0 ) 2 //=> returns the arguments in an array. 3 4 function butFirst () { 5 return Array . prototype . slice . call ( arguments , 1 ) 6 } 7 8 butFirst ( 'a' , 'b' , 'c' , 'd' ) 9 //=> [ 'b', 'c', 'd' ]

For simplicity and as a small speed improvement, slice is usually bound to a local variable:

1 var __slice = Array . prototype . slice ; 2 3 function butFirst () { 4 return __slice . call ( arguments , 1 ) 5 }

Or even:

1 var __slice = Array . prototype . slice ; 2 3 function slice ( list , from , to ) { 4 return __slice . call ( list , from , to ) 5 } 6 7 function butFirst () { 8 return slice ( arguments , 1 ) 9 }

concat

Arrays have another useful method, .concat . Concat returns an array created by concatenating the receiver with its argument:

1 [ 1 , 2 , 3 ]. concat ([ 2 , 1 ]) 2 //=> [1, 2, 3, 2, 1]

function lengths

Functions have a .length property that counts the number of arguments declared:

1 function ( a , b , c ) { return a + b + c }. length 2 //=> 3

3. Recipes with Basic Functions

Before combining ingredients, begin with implements so clean, they gleam.

Having looked at basic pure functions and closures, we’re going to see some practical recipes that focus on the premise of functions that return functions.

Disclaimer

The recipes are written for practicality, and their implementation may introduce JavaScript features that haven’t been discussed in the text to this point, such as methods and/or prototypes. The overall use of each recipe will fit within the spirit of the language discussed so far, even if the implementations may not.

Partial Application

In Building Blocks, we discussed partial application, but we didn’t write a generalized recipe for it. This is such a common tool that many libraries provide some form of partial application tool. You’ll find examples in Lemonad from Michael Fogus, Functional JavaScript from Oliver Steele and the terse but handy node-ap from James Halliday.

These two recipes are for quickly and simply applying a single argument, either the leftmost or rightmost.1 If you want to bind more than one argument, or you want to leave a “hole” in the argument list, you will need to either use a generalized partial recipe, or you will need to repeatedly apply arguments. It is context-agnostic.

1 var __slice = Array . prototype . slice ; 2 3 function callFirst ( fn , larg ) { 4 return function () { 5 var args = __slice . call ( arguments , 0 ); 6 7 return fn . apply ( this , [ larg ]. concat ( args )) 8 } 9 } 10 11 function callLast ( fn , rarg ) { 12 return function () { 13 var args = __slice . call ( arguments , 0 ); 14 15 return fn . apply ( this , args . concat ([ rarg ])) 16 } 17 } 18 19 function greet ( me , you ) { 20 return "Hello, " + you + ", my name is " + me 21 } 22 23 var heliosSaysHello = callFirst ( greet , 'Helios' ); 24 25 heliosSaysHello ( 'Eartha' ) 26 //=> 'Hello, Eartha, my name is Helios' 27 28 var sayHelloToCeline = callLast ( greet , 'Celine' ); 29 30 sayHelloToCeline ( 'Eartha' ) 31 //=> 'Hello, Celine, my name is Eartha'

As noted above, our partial recipe allows us to create functions that are partial applications of functions that are context aware. We’d need a different recipe if we wish to create partial applications of object methods.

Ellipses and improved Partial Application

The CoffeeScript programming language has a useful feature: If a parameter of a method is written with trailing ellipses, it collects a list of parameters into an array. It can be used in various ways, and the CoffeeScript transpiler does some pattern matching to sort things out, but 80% of the use is to collect a variable number of arguments without using the arguments pseudo-variable, and 19% of the uses are to collect a trailing list of arguments.

Here’s what it looks like collecting a variable number of arguments and trailing arguments:

1 callLeft = ( fn , args ...) -> 2 ( remainingArgs ...) -> 3 fn . apply ( this , args . concat ( remainingArgs ))

These are very handy features. Here’s our bogus, made-up attempt to write our own mapper function:

1 mapper = ( fn , elements ...) -> 2 elements . map ( fn ) 3 4 mapper (( x ) -> x * x ), 1 , 2 , 3 5 # => [ 1 , 4 , 9 ] 6 7 squarer = callLeft mapper , ( x ) -> x * x 8 9 squarer 1 , 2 , 3 10 # => [ 1 , 4 , 9 ]

JavaScript doesn’t support ellipses, those trailing periods CoffeeScript uses to collect arguments into an array. JavaScript is a functional language, so here is the recipe for a function that collects trailing arguments into an array for us:

1 var __slice = Array . prototype . slice ; 2 3 function variadic ( fn ) { 4 var fnLength = fn . length ; 5 6 if ( fnLength < 1 ) { 7 return fn ; 8 } 9 else if ( fnLength === 1 ) { 10 return function () { 11 return fn . call ( 12 this , __slice . call ( arguments , 0 )) 13 } 14 } 15 else { 16 return function () { 17 var numberOfArgs = arguments . length , 18 namedArgs = __slice . call ( 19 arguments , 0 , fnLength - 1 ), 20 numberOfMissingNamedArgs = Math . max ( 21 fnLength - numberOfArgs - 1 , 0 ), 22 argPadding = new Array ( numberOfMissingNamedArgs ), 23 variadicArgs = __slice . call ( 24 arguments , fn . length - 1 ); 25 26 return fn . apply ( 27 this , namedArgs 28 . concat ( argPadding ) 29 . concat ([ variadicArgs ])); 30 } 31 } 32 }; 33 34 function unary ( first ) { 35 return first 36 } 37 38 unary ( 'why' , 'hello' , 'there' ) 39 //=> 'why' 40 41 variadic ( unary )( 'why' , 'hello' , 'there' ) 42 //=> [ 'why', 'hello', 'there' ] 43 44 function binary ( first , rest ) { 45 return [ first , rest ] 46 } 47 48 binary ( 'why' , 'hello' , 'there' ) 49 //=> [ 'why', 'hello' ] 50 51 variadic ( binary )( 'why' , 'hello' , 'there' ) 52 //=> [ 'why', [ 'hello', 'there' ] ]

Here’s what we write to create our partial application functions gently:

1 var callLeft = variadic ( function ( fn , args ) { 2 return variadic ( function ( remainingArgs ) { 3 return fn . apply ( this , args . concat ( remainingArgs )) 4 }) 5 }) 6 7 // Let's try it! 8 9 var mapper = variadic ( function ( fn , elements ) { 10 return elements . map ( fn ) 11 }); 12 13 mapper ( function ( x ) { return x * x }, 1 , 2 , 3 ) 14 //=> [1, 4, 9] 15 16 var squarer = callLeft ( mapper , function ( x ) { return x * x }); 17 18 squarer ( 1 , 2 , 3 ) 19 //=> [1, 4, 9]

While we’re at it, here’s our implementation of callRight using the same technique:

1 var callRight = variadic ( function ( fn , args ) { 2 return variadic ( function ( precedingArgs ) { 3 return fn . apply ( this , precedingArgs . concat ( args )) 4 }) 5 })

Fine print: Of course, variadic introduces an extra function call and may not be the best choice in a highly performance-critical piece of code. Then again, using arguments is considerably slower than directly accessing argument bindings, so if the performance is that critical, maybe you shouldn’t be using a variable number of arguments in that section.

Unary

In Ellipses, we saw a function decorator that takes a function with a fixed number of arguments and turns it into a variadic function, a function taking any number of arguments. “Unary” is another function decorator, and it also modifies the number of arguments a function takes: Unary takes any function and turns it into a function taking exactly one argument.

The most common use case is to fix a common problem. JavaScript has a .map method for arrays, and many libraries offer a map function with the same semantics. Here it is in action:

1 [ '1' , '2' , '3' ]. map ( parseFloat ) 2 //=> [1, 2, 3]

In that example, it looks exactly like the mapping function you’ll find in most languages: You pass it a function, and it calls the function with one argument, the element of the array. However, that’s not the whole story. JavaScript’s map actually calls each function with three arguments: The element, the index of the element in the array, and the array itself.

Let’s try it:

1 [ 1 , 2 , 3 ]. map ( function ( element , index , arr ) { 2 console . log ({ element : element , index : index , arr : arr }) 3 }) 4 //=> { element: 1, index: 0, arr: [ 1, 2, 3 ] } 5 // { element: 2, index: 1, arr: [ 1, 2, 3 ] } 6 // { element: 3, index: 2, arr: [ 1, 2, 3 ] }

If you pass in a function taking only one argument, it simply ignores the additional arguments. But some functions have optional second or even third arguments. For example:

1 [ '1' , '2' , '3' ]. map ( parseInt ) 2 //=> [1, NaN, NaN]

This doesn’t work because parseInt is defined as parseInt(string[, radix]) . It takes an optional radix argument. And when you call parseInt with map , the index is interpreted as a radix. Not good! What we want is to convert parseInt into a function taking only one argument.

We could write ['1', '2', '3'].map(function (s) { return parseInt(s); }) , or we could come up with a decorator to do the job for us:

1 function unary ( fn ) { 2 if ( fn . length == 1 ) { 3 return fn 4 } 5 else return function ( something ) { 6 return fn . call ( this , something ) 7 } 8 }

And now we can write:

1 [ '1' , '2' , '3' ]. map ( unary ( parseInt )) 2 //=> [1, 2, 3]

Presto!

Tap

One of the most basic combinators is the “K Combinator,” nicknamed the “kestrel:”

1 function K ( x ) { 2 return function ( y ) { 3 return x 4 } 5 };

It has some surprising applications. One is when you want to do something with a value for side-effects, but keep the value around. Behold:

1 function tap ( value ) { 2 return function ( fn ) { 3 if ( typeof ( fn ) === 'function' ) { 4 fn ( value ) 5 } 6 return value 7 } 8 }

tap is a traditional name borrowed from various Unix shell commands. It takes a value and returns a function that always returns the value, but if you pass it a function, it executes the function for side-effects. Let’s see it in action as a poor-man’s debugger:

1 var drink = tap ( 'espresso' )( function ( it ) { 2 console . log ( "Our drink is" , it ) 3 }); 4 5 // outputs "Our drink is 'espresso'" to the console

It’s easy to turn off:

1 var drink = tap ( 'espresso' )(); 2 3 // doesn't output anything to the console

Libraries like Underscore use a version of tap that is “uncurried:”

1 var drink = _ . tap ( 'espresso' , function () { 2 console . log ( "Our drink is" , this ) 3 });

Let’s enhance our recipe so it works both ways:

1 function tap ( value , fn ) { 2 if ( fn === void 0 ) { 3 return curried 4 } 5 else return curried ( fn ); 6 7 function curried ( fn ) { 8 if ( typeof ( fn ) === 'function' ) { 9 fn ( value ) 10 } 11 return value 12 } 13 }

Now you can write:

1 var drink = tap ( 'espresso' )( function ( it ) { 2 console . log ( "Our drink is" , it ) 3 });

Or:

1 var drink = tap ( 'espresso' , function ( it ) { 2 console . log ( "Our drink is" , it ) 3 });

And if you wish it to do nothing at all, You can write either:

1 var drink = tap ( 'espresso' )();

Or:

1 var drink = tap ( 'espresso' , null );

tap can do more than just act as a debugging aid. It’s also useful for working with object and instance methods.

Maybe

A common problem in programming is checking for null or undefined (hereafter called “nothing,” while all other values including 0 , [] and false will be called “something”). Languages like JavaScript do not strongly enforce the notion that a particular variable or particular property be something, so programs are often written to account for values that may be nothing.

This recipe concerns a pattern that is very common: A function fn takes a value as a parameter, and its behaviour by design is to do nothing if the parameter is nothing:

1 function isSomething ( value ) { 2 return value !== null && value !== void 0 ; 3 } 4 5 function checksForSomething ( value ) { 6 if ( isSomething ( value )) { 7 // function's true logic 8 } 9 }

Alternately, the function may be intended to work with any value, but the code calling the function wishes to emulate the behaviour of doing nothing by design when given nothing:

1 var something = isSomething ( value ) ? 2 doesntCheckForSomething ( value ) : value ;

Naturally, there’s a recipe for that, borrowed from Haskell’s maybe monad, Ruby’s andand, and CoffeeScript’s existential method invocation:

1 function maybe ( fn ) { 2 return function () { 3 var i ; 4 5 if ( arguments . length === 0 ) { 6 return 7 } 8 else { 9 for ( i = 0 ; i < arguments . length ; ++ i ) { 10 if ( arguments [ i ] == null ) return 11 } 12 return fn . apply ( this , arguments ) 13 } 14 } 15 }

maybe reduces the logic of checking for nothing to a function call, either:

1 var checksForSomething = maybe ( function ( value ) { 2 // function's true logic 3 });

Or:

1 var something = maybe ( doesntCheckForSomething )( value );

As a bonus, maybe plays very nicely with instance methods, we’ll discuss those later:

1 function Model () {}; 2 3 Model . prototype . setSomething = maybe ( function ( value ) { 4 this . something = value ; 5 });

If some code ever tries to call model.setSomething with nothing, the operation will be skipped.

4. The Pause That Refreshes: Rebinding and References

It is not enough that coffee taste beautiful. Everything about its creation and consumption should reflect coffee’s beauty.

a simple question

Consider this code:

1 var x = 'June 14, 1962' , 2 y = x ; 3 4 x === y 5 //=> true

This makes obvious sense, because we know that strings are a value type, so no matter what expression you use to derive the value ‘June 14, 1962’, you are going to get a string with the exact same identity.

But what about this code?

1 var x = [ 2012 , 6 , 14 ], 2 y = x ; 3 4 x === y 5 //=> true

Also true, even though we know that every time we evaluate an expression such as [2012, 6, 14] , we get a new array with a new identity. So what is happening in our environments?

arguments and references

In our discussion of closures, we said that environments bind values (like [2012, 6, 14] ) to names (like x and y ), and that when we use these names as expressions, the name evaluates as the value.

What this means is that when we write something like y = x , the name x is looked up in the current environment, and its value is a specific array that was created when the expression [2012, 6, 14] was first evaluated. We then bind that exact same value to the name y in a new environment, and thus x and y are both bound to the exact same value, which is identical to itself.

The same thing happens with binding a variable through a more conventional means of applying a function to arguments:

1 var x = [ 2012 , 6 , 14 ]; 2 3 ( function ( y ) { 4 return x === y 5 })( x ) 6 //=> true

x and y both end up bound to the exact same array, not two different arrays that look the same to our eyes.

Arguments and Arrays

JavaScript provides two different kinds of containers for values. We’ve met one already, the array. Let’s see how it treats values and identities. For starters, we’ll learn how to extract a value from an array. We’ll start with a function that makes a new value with a unique identity every time we call it. We already know that every function we create is unique, so that’s what we’ll use:

1 var unique = function () { 2 return function () {} 3 }; 4 5 unique () 6 //=> [Function] 7 8 unique () === unique () 9 //=> false

Let’s verify that what we said about references applies to functions as well as arrays:

1 var x = unique (), 2 y = x ; 3 4 x === y 5 //=> true

Ok. So what about things inside arrays? We know how to create an array with something inside it:

1 [ unique () ] 2 //=> [ [Function] ]

That’s an array with one of our unique functions in it. How do we get something out of it?

1 var a = [ 'hello' ]; 2 3 a [ 0 ] 4 //=> 'hello'

Cool, arrays work a lot like arrays in other languages and are zero-based. The trouble with this example is that strings are value types in JavaScript, so we have no idea whether a[0] always gives us the same value back like looking up a name in an environment, or whether it does some magic that tries to give us a new value.

We need to put a reference type into an array. If we get the same thing back, we know that the array stores a reference to whatever you put into it. If you get something different back, you know that arrays store copies of things.1

Let’s test it:

1 var unique = function () { 2 return function () {} 3 }, 4 x = unique (), 5 a = [ x ]; 6 7 a [ 0 ] === x 8 //=> true

If we get a value out of an array using the [] suffix, it’s the exact same value with the same identity. Question: Does that apply to other locations in the array? Yes:

1 var unique = function () { 2 return function () {} 3 }, 4 x = unique (), 5 y = unique (), 6 z = unique (), 7 a = [ x , y , z ]; 8 9 a [ 0 ] === x && a [ 1 ] === y && a [ 2 ] === z 10 //=> true

References and Objects

JavaScript also provides objects. The word “object” is loaded in programming circles, due to the widespread use of the term “object-oriented programming” that was coined by Alan Kay but has since come to mean many, many things to many different people.

In JavaScript, an object2 is a map from names to values, a lot like an environment. The most common syntax for creating an object is simple:

Two objects created this way have differing identities, just like arrays:

1 { year : 2012 , month : 6 , day : 14 } === { year : 2012 , month : 6 , day : 14 } 2 //=> false

Objects use [] to access the values by name, using a string:

1 { year : 2012 , month : 6 , day : 14 }[ 'day' ] 2 //=> 14

Values contained within an object work just like values contained within an array:

1 var unique = function () { 2 return function () {} 3 }, 4 x = unique (), 5 y = unique (), 6 z = unique (), 7 o = { a : x , b : y , c : z }; 8 9 o [ 'a' ] === x && o [ 'b' ] === y && o [ 'c' ] === z 10 //=> true

Names needn’t be alphanumeric strings. For anything else, enclose the label in quotes:

1 { 'first name' : 'reginald' , 'last name' : 'lewis' }[ 'first name' ] 2 //=> 'reginald'

If the name is an alphanumeric string conforming to the same rules as names of variables, there’s a simplified syntax for accessing the values:

1 { year : 2012 , month : 6 , day : 14 }[ 'day' ] === 2 { year : 2012 , month : 6 , day : 14 }. day 3 //=> true

All containers can contain any value, including functions or other containers:

1 var Mathematics = { 2 abs : function ( a ) { 3 return a < 0 ? - a : a 4 } 5 }; 6 7 Mathematics . abs ( - 5 ) 8 //=> 5

Funny we should mention Mathematics . If you recall, JavaScript provides a global environment that contains some existing objects that have handy functions you can use. One of them is called Math , and it contains functions for abs , max , min , and many others. Since it is always available, you can use it in any environment provided you don’t shadow Math .

1 Math . abs ( - 5 ) 2 //=> 5

Reassignment and Mutation

Like most imperative programming languages, JavaScript allows you to re-assign the value of variables. The syntax is familiar to users of most popular languages:

1 var age = 49 ; 2 age = 50 ; 3 age 4 //=> 50

We took the time to carefully examine what happens with bindings in environments. Let’s take the time to explore what happens with reassigning values to variables. The key is to understand that we are rebinding a different value to the same name in the same environment.

So let’s consider what happens with a shadowed variable:

1 ( function () { 2 var age = 49 ; 3 ( function () { 4 var age = 50 ; 5 })(); 6 return age ; 7 })() 8 //=> 49

Binding 50 to age in the inner environment does not change age in the outer environment because the binding of age in the inner environment shadows the binding of age in the outer environment. We go from:

1 { age : 49 , '..' : global - environment }

To:

1 { age : 50 , '..' : { age : 49 , '..' : global - environment }}

Then back to:

1 { age : 49 , '..' : global - environment }

However, if we don’t shadow age by explicitly using var , reassigning it in a nested environment changes the original:

1 ( function () { 2 var age = 49 ; 3 ( function () { 4 age = 50 ; 5 })(); 6 return age ; 7 })() 8 //=> 50

Like evaluating variable labels, when a binding is rebound, JavaScript searches for the binding in the current environment and then each ancestor in turn until it finds one. It then rebinds the name in that environment.

Cupping Grinds

mutation and aliases

Now that we can reassign things, there’s another important factor to consider: Some values can mutate. Their identities stay the same, but not their structure. Specifically, arrays and objects can mutate. Recall that you can access a value from within an array or an object using [] . You can reassign a value using [] as well:

1 var oneTwoThree = [ 1 , 2 , 3 ]; 2 oneTwoThree [ 0 ] = 'one' ; 3 oneTwoThree 4 //=> [ 'one', 2, 3 ]

You can even add a value:

1 var oneTwoThree = [ 1 , 2 , 3 ]; 2 oneTwoThree [ 3 ] = 'four' ; 3 oneTwoThree 4 //=> [ 1, 2, 3, 'four' ]

You can do the same thing with both syntaxes for accessing objects:

1 var name = { firstName : 'Leonard' , lastName : 'Braithwaite' }; 2 name . middleName = 'Austin' 3 name 4 //=> { firstName: 'Leonard', 5 # lastName : 'Braithwaite' , 6 # middleName : 'Austin' }

We have established that JavaScript’s semantics allow for two different bindings to refer to the same value. For example:

1 var allHallowsEve = [ 2012 , 10 , 31 ] 2 var halloween = allHallowsEve ;

Both halloween and allHallowsEve are bound to the same array value within the local environment. And also:

1 var allHallowsEve = [ 2012 , 10 , 31 ]; 2 ( function ( halloween ) { 3 // ... 4 })( allHallowsEve );

There are two nested environments, and each one binds a name to the exact same array value. In each of these examples, we have created two aliases for the same value. Before we could reassign things, the most important point about this is that the identities were the same, because they were the same value.

This is vital. Consider what we already know about shadowing:

1 var allHallowsEve = [ 2012 , 10 , 31 ]; 2 ( function ( halloween ) { 3 halloween = [ 2013 , 10 , 31 ]; 4 })( allHallowsEve ); 5 allHallowsEve 6 //=> [2012, 10, 31]

The outer value of allHallowsEve was not changed because all we did was rebind the name halloween within the inner environment. However, what happens if we mutate the value in the inner environment?

1 var allHallowsEve = [ 2012 , 10 , 31 ]; 2 ( function ( halloween ) { 3 halloween [ 0 ] = 2013 ; 4 })( allHallowsEve ); 5 allHallowsEve 6 //=> [2013, 10, 31]

This is different. We haven’t rebound the inner name to a different variable, we’ve mutated the value that both bindings share. Now that we’ve finished with mutation and aliases, let’s have a look at it.

JavaScript permits the reassignment of new values to existing bindings, as well as the reassignment and assignment of new values to elements of containers such as arrays and objects. Mutating existing objects has special implications when two bindings are aliases of the same value.

As we’ve seen, JavaScript’s environments and bindings are quite powerful: You can bind and rebind names using function arguments or using variables declared with var . The takeaway is that when used properly, Javascript’s var keyword is a great tool.

When used properly.

Let’s look at a few ways to use it improperly.

loose use

JavaScript’s var keyword is scoped to the function enclosing it. This makes sense, because bindings are made in environments, and the environments are associated with function calls. So if you write:

1 function foo ( bar ) { 2 var baz = bar * 2 ; 3 4 if ( bar > 1 ) { 5 var blitz = baz - 100 ; 6 7 // ... 8 } 9 }

The name blitz is actually scoped to the function foo , not to the block of code in the consequent of an if statement. There are roughly two schools of thought. One line of reasoning goes like this: Since blitz is scoped to the function foo , you should write the code like this:

1 function foo ( bar ) { 2 var baz = bar * 2 , 3 blitz ; 4 5 if ( bar > 1 ) { 6 blitz = baz - 100 ; 7 8 // ... 9 } 10 }

We’ve separated the “declaration” from the “assignment,” and we’ve made it clear that blitz is scoped to the entire function. The other school of thought is that programmers are responsible for understanding how the tools work, and even if you write it the first way, other programmers reading the code ought to know how it works.

So here’s a question: Are both ways of writing the code equivalent? Let’s set up a test case that would tell them apart. We’ll try some aliasing:

1 var questionable = 'outer' ; 2 3 ( function () { 4 alert ( questionable ); 5 6 if ( true ) { 7 var questionable = 'inner' ; 8 alert ( questionable ) 9 } 10 })()

What will this code do if we type it into a browser console? One theory is that it will alert outer and then inner , because when it evaluates the first alert, questionable hasn’t been bound in the function’s environment yet, so it will be looked up in the enclosing environment. Then an alias is bound, shadowing the outer binding, and it will alert inner .

This theory is wrong! It actually alerts undefined and then inner . Even though we wrote the var statement later in the code, JavaScript acts as if we’d declared it at the top of the function. This is true even if we never execute the var statement:

1 var questionable = 'outer' ; 2 3 ( function () { 4 return questionable ; 5 6 var questionable = 'inner' 7 })() 8 9 //=> undefined

So yes, both ways of writing the code work the same way, but only one represents the way it works directly and obviously. For this reason, we put the var declarations at the top of every function, always.

for pete’s sake

JavaScript provides a for loop for your iterating pleasure and convenience. It looks a lot like the for loop in C:

1 var sum = 0 ; 2 for ( var i = 1 ; i <= 100 ; i ++ ) { 3 sum = sum + i 4 } 5 sum 6 # => 5050

Hopefully, you can think of a faster way to calculate this sum.3 And perhaps you have noticed that var i = 1 is tucked away instead of being at the top as we prefer. But is this ever a problem?

Yes. Consider this variation:

1 var introductions = [], 2 names = [ 'Karl' , 'Friedrich' , 'Gauss' ]; 3 4 for ( var i = 0 ; i < 3 ; i ++ ) { 5 introductions [ i ] = "Hello, my name is " + names [ i ] 6 } 7 introductions 8 //=> [ 'Hello, my name is Karl', 9 // 'Hello, my name is Friedrich', 10 // 'Hello, my name is Gauss' ]

So far, so good. Hey, remember that functions in JavaScript are values? Let’s get fancy!

1 var introductions = [], 2 names = [ 'Karl' , 'Friedrich' , 'Gauss' ]; 3 4 for ( var i = 0 ; i < 3 ; i ++ ) { 5 introductions [ i ] = function ( soAndSo ) { 6 return "Hello, " + soAndSo + ", my name is " + names [ i ] 7 } 8 } 9 introductions 10 //=> [ [Function], 11 // [Function], 12 // [Function] ]

So far, so good. Let’s try one of our functions:

1 introductions [ 1 ]( 'Raganwald' ) 2 //=> 'Hello, Raganwald, my name is undefined'

What went wrong? Why didn’t it give us ‘Hello, Raganwald, my name is Friedrich’? The answer is that pesky var i . Remember that i is bound in the surrounding environment, so it’s as if we wrote:

1 var introductions = [], 2 names = [ 'Karl' , 'Friedrich' , 'Gauss' ], 3 i ; 4 5 for ( i = 0 ; i < 3 ; i ++ ) { 6 introductions [ i ] = function ( soAndSo ) { 7 return "Hello, " + soAndSo + ", my name is " + names [ i ] 8 } 9 } 10 introductions

Now, at the time we created each function, i had a sensible value, like 0 , 1 , or 2 . But at the time we call one of the functions, i has the value 3 , which is why the loop terminated. So when the function is called, JavaScript looks i up in its enclosing environment (its closure, obviously), and gets the value 3 . That’s not what we want at all.

Here’s how to fix it, once again with let as our guide:

1 var introductions = [], 2 names = [ 'Karl' , 'Friedrich' , 'Gauss' ]; 3 4 for ( var i = 0 ; i < 3 ; i ++ ) { 5 ( function ( i ) { 6 introductions [ i ] = function ( soAndSo ) { 7 return "Hello, " + soAndSo + ", my name is " + names [ i ] 8 } 9 })( i ) 10 } 11 introductions [ 1 ]( 'Raganwald' ) 12 //=> 'Hello, Raganwald, my name is Friedrich'

That works. What did we do? Well, we created a new function and called it immediately, and we deliberately shadowed i by passing it as an argument to our function, which had an argument of exactly the same name. If you dislike shadowing, this alternative also works:

1 var introductions = [], 2 names = [ 'Karl' , 'Friedrich' , 'Gauss' ]; 3 4 for ( var i = 0 ; i < 3 ; i ++ ) { 5 ( function () { 6 var ii = i ; 7 introductions [ ii ] = function ( soAndSo ) { 8 return "Hello, " + soAndSo + ", my name is " + names [ ii ] 9 } 10 })() 11 } 12 introductions [ 1 ]( 'Raganwald' ) 13 //=> 'Hello, Raganwald, my name is Friedrich'

Now we’re creating a new inner variable, ii and binding it to the value of i . The shadowing code seems simpler and less error-prone to us, but both work.

nope, nope, nope, nope, nope

The final caution about var concerns what happens if you omit to declare a variable with var, boldly writing something like:

1 fizzBuzz = function () { 2 // lots of interesting code elided 3 // for the sake of hiring managers 4 }

So where is the name fizzBuzz bound? The answer is that if there is no enclosing var declaration for fizzBuzz , the name is bound in the global environment. And by global, we mean global. It is visible to every separate compilation unit. All of your npm modules. Every JavaScript snippet in a web page. Every included file.

This is almost never what you want. And when you do want it, JavaScript provides alternatives such as binding to window.fizzBuzz in a browser, or this.fizzBuzz in node. In short, eschew undeclared variables. Force yourself to make a habit of using var all of the time, and explicitly binding variables to the window or this objects when you truly want global visibility.

When Rebinding Meets Recursion

We’ve talked about binding values in environments, and now we’re talking about rebinding values and mutating values. Let’s take a small digression. As we’ve seen, in JavaScript functions are values. So you can bind a function just like binding a string, number or array. Here’s a function that tells us whether a (small and positive) number is even:

1 var even = function ( num ) { 2 return ( num === 0 ) || ! ( even ( num - 1 )) 3 } 4 5 even ( 0 ) 6 //=> true 7 8 even ( 1 ) 9 //=> false 10 11 even ( 42 ) 12 //=> true

You can alias a function value:

1 var divisibleByTwo = even ; 2 3 divisibleByTwo ( 0 ) 4 //=> true 5 6 divisibleByTwo ( 1 ) 7 //=> false 8 9 divisibleByTwo ( 42 ) 10 //=> true

What happens when we redefine a recursive function like even ? Does divisibleByTwo still work? Let’s try aliasing it and reassigning it:

1 even = void 0 ; 2 3 divisibleByTwo ( 0 ) 4 //=> true 5 6 divisibleByTwo ( 1 ) 7 //=> TypeError

What happened? Well, our new divisibleByTwo function wasn’t really a self-contained value. When we looked at functions, we talked about “pure” functions that only access their arguments and we looked at “closures” that have free variables. Recursive functions defined like this are closures, not pure functions, because when they “call themselves,” what they actually do is look themselves up by name in their enclosing environment. Thus, they depend upon a specific value (themselves) being bound in their enclosing environment. Reassign to that variable (or rebind the name, same thing), and you break their functionality.

named function expressions

You recall that in Naming Functions, we saw that when you create a named function expression, you bind the name of the function within its body but not the environment of the function expression, meaning you can write:

1 var even = function myself ( num ) { 2 return ( num === 0 ) || ! ( myself ( num - 1 )) 3 } 4 5 var divisibleByTwo = even ; 6 even = void 0 ; 7 8 divisibleByTwo ( 0 ) 9 //=> true 10 11 divisibleByTwo ( 1 ) 12 //=> false 13 14 divisibleByTwo ( 42 ) 15 //=> true

This is different, because the function doesn’t refer to a name bound in its enclosing environment, it refers to a name bound in its own body. It is now a pure function. In fact, you can even bind it to the exact same name in its enclosing environment and it will still work:

1 var even = function even ( num ) { 2 return ( num === 0 ) || ! ( even ( num - 1 )) 3 } 4 5 var divisibleByTwo = even ; 6 even = void 0 ; 7 8 divisibleByTwo ( 0 ) 9 //=> true 10 11 divisibleByTwo ( 1 ) 12 //=> false 13 14 divisibleByTwo ( 42 ) 15 //=> true

The even inside the function refers to the name bound within the function by the named function expression. It may have the same name as the even bound in the enclosing environment, but they are two different bindings in two different environments. Thus, rebinding the name in the enclosing environment does not break the function.

You may ask, what if we rebind even inside of itself. Now will it break?

1 var even = function even ( num ) { 2 even = void 0 ; 3 return ( num === 0 ) || ! ( even ( num - 1 )) 4 } 5 6 var divisibleByTwo = even ; 7 even = void 0 ; 8 9 divisibleByTwo ( 0 ) 10 //=> true 11 12 divisibleByTwo ( 1 ) 13 //=> false 14 15 divisibleByTwo ( 42 ) 16 //=> true

Strangely, no it doesn’t. The name bound by a named function expression is read-only. Why do we say strangely? Because other quasi-declarations like function declarations do not behave like this.

So, when we want to make a recursive function, the safest practice is to use a named function expression.

limits

Named function expressions have limits. Here’s one such limit: You can do simple recursion, but not mutual recursion. For example:

1 var even = function even ( num ) { return ( num === 0 ) || odd ( num - 1 ) }; 2 var odd = function odd ( num ) { return ( num > 0 ) && even ( num - 1 ) }; 3 4 odd = 'unusual' ; 5 6 even ( 0 ) 7 //=> true 8 9 even ( 1 ) 10 //=> TypeError

Using named function expressions doesn’t help us, because even and odd need to be bound in an environment accessible to each other, not just to themselves. You either have to avoid rebinding the names of these functions, or use a closure to build a module:

1 var operations = ( function () { 2 var even = functi