Skip to content
25 changes: 7 additions & 18 deletions common-content/en/module/js1/anonymous-functions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,26 @@ function convertToPercentage(decimalNumber) {
}
```

In our Jest test, we wrote a function differently:
In our tests we wrote the functions differently:

```js
function() {
expect(getOrdinalNumber(1)).toEqual("1st");
expect(getOrdinalNumber(11)).toEqual("11th");
expect(getOrdinalNumber(21)).toEqual("21st");
function(){
assert.equal(formatAs12HourClock("23:00"), "11:00 pm");
}
```
Note the difference between the two: we didn't give a name to the function in our test.

{{<note type="exercise" title="👀 Spot the difference">}}

Stop and identify the difference in syntax between these two function definitions.

{{</note>}}

We didn't give a name to the function in our Jest test.

This is ok, because we don't need it to have a name. We don't call the function by name. We passed the function as an {{<tooltip title="argument">}}Arguments are values given to a function which can be different every time we call the function.{{</tooltip>}} to the `test` function. The `test` function takes the function as a {{<tooltip title="parameter">}}A parameter is a named variable inside a function. The variable's value is given by the caller, when the function is called.{{</tooltip>}}. And function parameters get their own names in the {{<tooltip title="scope">}}Scope is where a variable can be accessed from. When we define function, its parameters are only available inside the function.{{</tooltip>}} of the function.
This is ok, because we don't need it to have a name. We don't call the function by name. We passed the function as an argument to the `test` function. When we execute the code Node will create its own label internally and use that when it needs to reference the function.

We can imagine the `test` function is defined like this:

```js
function test(name, testFunction) {
function test(label, testFunction) {
// Call the passed test function
testFunction();
}
```

Inside `test` our function is labelled with the name `testFunction`. It would be labelled this whatever we named it before. Even if we didn't label it ourselves at all, it is still labelled with the name `testFunction` inside `test`.

Because it doesn't matter what we named the function (because we never call it by name), we didn't give it a name.
The internal label attached to the function by Node doesn't matter because the function will only ever be called by Node. We will never need to use it again outside of this test.

Otherwise, these two functions act the same. The only difference between them is whether we created a variable name for the function in the scope where we defined it.
69 changes: 48 additions & 21 deletions common-content/en/module/js1/arrow-functions/index.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,93 @@
+++
title = 'Arrow functions'

time = 5
time = 20
[objectives]
1='Write an arrow function'
2="Call a function which has been stored in a variable"
[build]
render = 'never'
list = 'local'
publishResources = false

+++

As we write more code, we are going to write lots and lots of {{<tooltip title="anonymous functions">}}An anonymous function is a function which is not bound to a name in the scope where it is defined.{{</tooltip>}}.
As we progress through this course we will find lots of situations where we can use anonymous functions. In this section we'll see how we can make them even shorter by removing the `function` keyword and in some cases reducing everything to a single line.

JavaScript has even shorter ways of writing an anonymous function. These four functions all do the same thing:
### Types of functions

We have already seen lots of examples of **named functions**. These are functions defined like we did in the previous module.

```js
function convertToPercentage(decimalNumber) {
return `${decimalNumber * 100}%`;
}
```

In the last section we introduced the concept of **anonymous functions** where we don't need to assign a name to the function.

```js
// We can skip the name of the function if we don't need it to have a name.
function (decimalNumber) {
return `${decimalNumber * 100}%`;
}
```

The `function` keyword isn't the only way for us to define a function. In modern versions of JavaScript we can leave it out, but we still need a way of linking the list of parameters to the function body. We use an arrow symbol (`=>`) to do so and this is why we call anonymous functions defined this way **arrow functions**.

```js
// We can also skip the keyword 'function'.
// If we do this, we need an arrow between our parameters and the function body.
(decimalNumber) => {
return `${decimalNumber * 100}%`;
};
```

When using arrow functions we can go a step further and omit the braces and `return` keyword too. This is called an **implicit return** but it can only be used when the function body contains a single expression.

```js
// If our function just returns a single value,
// without needing any other statements in our function,
// we can even skip the return keyword.
(decimalNumber) => `${decimalNumber * 100}%`;
```

This can make it easier and quicker to write functions. It also reduces the number of things we need to read in a function.

Applying all of these techniques, we can rewrite our Jest test with fewer words:
{{<note type="exercise" title="Exercise: Using arrow functions">}}
Rewrite your tests in `timeConverter.test.js` to use arrow functions.

```js
test("works for any number ending in 1", () => {
expect(getOrdinalNumber(1)).toEqual("1st");
expect(getOrdinalNumber(11)).toEqual("11th");
expect(getOrdinalNumber(21)).toEqual("21st");
});
<details>
<summary>Solution:</summary>

```js {title="timeConverter.test.js"}
test("correctly convert time after 12:00", () => assert.equal(formatAs12HourClock("23:00"), "11:00 pm"));

test("can correctly convert morning time", () => assert.equal(formatAs12HourClock("08:00"),"08:00 am"));

test("can correctly convert midnight", () => assert.equal(formatAs12HourClock("00:00"),"12:00 am"));
```

It doesn't matter whether you use arrow functions or use the `function` keyword - they work the same.
We can use the implicit return syntax here because the `assert.equal()` call is the only expression in the function body.

Not all arrow functions are anonymous - you can assign them to a variable too:
</details>

```js
const convertToPercentage = (decimalNumber) => `${decimalNumber * 100}%`;
{{</note>}}

### Assigning functions to a variable

Our anonymous functions don't need to stay anonymous - we can assign them to a variable if we need to. When we want to call the function we can do so using the variable name, just like we would if it was a named function.

Create a new file to try this in.

```js {title="modifyingNumbers.js"}
const doubleNumber = function(number){
return number *2;
}

const halfNumber = (number) => number / 2;

console.log("doubled number:", doubleNumber(2));
console.log("halved number:", halfNumber(2));
```

Anonymous vs named refers to whether the function is bound to a name, not whether it was defined with the `function` keyword or an `=>`.
Running the file prints:

```console
doubled number: 4
halved number: 1
```
122 changes: 0 additions & 122 deletions common-content/en/module/js1/cases/index.md

This file was deleted.

43 changes: 0 additions & 43 deletions common-content/en/module/js1/clocks/index.md

This file was deleted.

Loading
Loading