Làm web (js04) - JS: Functions

Bài trước: Làm web (js03) - JS: Arrays, Logic and Loops
----------

4         Functions


A function is a chunk of code that can be referenced by a name, and is almost like a small, self-contained mini program. Functions can help reduce repetition and make code easier to follow.

In this chapter, we’ll be covering these topics:

– Defining functions―function declarations, function expressions, Function() constructors and the new arrow syntax

– Invoking a function

– Return values

– Parameters and arguments

– Hoisting―variables and functions

– Callbacks―functions as a parameter

– Project ― we’ll be using functions to make the Quiz Ninja code easier to follow

4.1       Defining a Function (p133)


Function declarations (p133)

function hello(){
console.log('Hello World!');
}

hello();

Lab 8. Write a program using function declaration. Program allows user input a number, then output the sum from 0 to that number.

Function Expression (p134) (anonymous function)

const goodbye = function(){
console.log('Goodbye World!');
};

or,

const goodbye = function bye(){
console.log('Goodbye World!');
};
goodbye();
bye() //error

Lab 9. Write a program using function expression. Program allows user input fullname, then output the fullname as uppercase.

Every function has a name (p135)

Using when debug to know which functions are causing a problem.

console.log(goodbye.name);

Function constructor (p135)

It is not recommended to use this way to declare a function.

4.2       Invoking a function (p136)

4.3       Return Values (p137)

4.4       Parameters and arguments (p138)


Variable numbers of arguments (p140)

Lab 10. Use rest parameter to write the function that allow to get the mean of any set of number.

A sample code:

function mean(...rest){
    let total = 0;
    for(item of rest){
        total += item;
    }
    return total/rest.length;
}
console.log(mean(1,2,1,2,3,4));

Arrow function (p145)

Function hoisting (p147)

Variable hosting (p148)

Variable hoisting can cause quite a bit of confusion and also relies on using var to declare variables. An error will be thrown if you attempt to refer to a variable before it has been declared using const and let. It’s better practice to use const and let to declare any variables at the beginning of a block so hoisting is unnecessary.

4.5       Callbacks (p149)


Remember at the start of this chapter when we said that functions in JavaScript are first-class objects, so they behave in just the same way as every other object? This means that functions can also be given as a parameter to another function. A function that is passed as an argument to another is known as a callback.

Consider a function:

function sing(song) {
console.log(`I'm singing along to ${song}`);
}
sing('Let It Go')
<< 'I'm singing along to Let It Go'

We can make the sing() function more flexible by adding a callback parameter:

function sing(song,callback) {
console.log(`I'm singing along to ${song}.`);
callback();
}

The callback is provided as a parameter, then invoked inside the body of the function.
But what if the function isn’t provided as an argument?

There is nothing to actually define a parameter as a callback, so if a function isn’t provided as an argument, then this code won’t work. It is possible to check if an argument is a function using the following code:

if(typeof(callback) === 'function '){
callback();
}

This will only attempt to invoke the callback if it is a function.

Now we can create another function called dance() that can be used as the callback:

function dance(){
console.log(‘I am moving my body to the groove.’);
}

Now we can call our sing function, but we can also dance as well as sing:

sing(‘Let it go’, dance);

Lab 11. Applying callback function.

As you known, arrays have sort() method to sort all items in array. Try with this array [1,3,12,5,23,18,7].sort();

The result is [1, 12, 18, 23, 3, 5, 7], what is happened? JavaScript has converted numerical array into strings, then placed in alphabetical order.

So, write a function to sort an array based on numerical values:

function numerically(a,b){
    return (a-b)
}

This function can now be used as a callback in the sort() method to sort the array of numbers correctly.

console.log(arr.sort(numerically));
// [1, 3, 5, 7, 12, 18, 23]

Code sample:

const arr = [1,3,12,5,23,18,7];
// console.log(arr.sort());
function numerically(a,b){
    return (a-b)
}
console.log(arr.sort(numerically));

4.6       Array Iterators (p153)


Arrays have a number of methods that utilize callbacks to make them more flexible.

– forEach()

In the last chapter, you can use a for loop to loop through each value in an array like so:

const colors = ['Red', 'Green', 'Blue'];
for(let i = 0; i < colors.length; i++){
    console.log(`Color at position ${i} is ${colors[i]}`);
}

An alternative is to use the forEach() method. This will loop through the array and invoke a callback function using each value as an argument. The callback function takes three parameters, the first represents the value in the array, the second represents the current index and the third represent the array tha the callback is being called on. The example above could be written as:

colors.forEach( (color, index) =>  { console.log(`Color at position ${index} is ${color}`);});

or,

colors.forEach( (color, index) =>  {
    console.log(`Color at position ${index} is ${color}`);
});

or,

colors.forEach( (color, index) =>  console.log(`Color at position ${index} is ${color}`));

– map() (p154)

For example,

console.log([1,2,3].map( square ));
function square (x) {
    return x*x;
}
//> [1, 4, 9]

An anonymous function can also be used as a callback. This example will double all the number in the array:

console.log([1,2,3].map( x => x * 2 ));
//>[2, 4, 6]

or,

console.log([1,2,3].map( (x) => x * 2 ));

or,

console.log([1,2,3].map( (x) => {
    return x * 2;
 }));

The next example takes each item in the array and places them in uppercase inside paragraph HTML tags:

const result = ['red', 'green', 'blue'].map( color => `<p>${color.toUpperCase()}</p>` );
document.write(result);

Notice in this and the previous example, the anonymous function take a parameter, color, which refers to the item in the array. This callback can also take two more parameters–the second parameter refers to the index number in the array and the third refers to the array itself. It’s quite common for callbacks to only used the first, index, parameter, but the next example shows all three parameters being used:

console.log(['red', 'green', 'blue'].map( (color, index, array) => `Element ${index} is ${color}. There are ${array.length} items in total.` ));
//> "Element 0 is red. There are 3 items in total.", "Element 1 is green. There are 3 items in total.", "Element 2 is blue. There are 3 items in total."

Lab 12. Give an array with numerical values, for example [1,2,3,4]. Write a chunk of code to write browser a list as following:

1. Item 1
2. Item 2
3. Item 3
4. Item 4

[Sample]

const so = [1,2,3,4];

document.write("<ol>");
so.map( (x) => document.write(`<li> Mục ${x} </li>`) );
document.write("</ol>");

Lab 13. Given an array with lower characters (for example [le, van, teo]),  Write a chunk of code convert lower characters into upper characters (for example [LE, VAN, TEO]).

[Sample]

const name = ['le','van','teo'];
const result = name.map( (char) => char.toUpperCase());

console.log(result);

– reduce() (p155)

The reduce() method is another method that iterates over each value in the array, but this time it cumulatively combines each result to return just a single value. The callback function is used to describe how to combine each value of the array with the running total. This is often used  to calculate statistics such as averages from data stored in an array. It usually takes two parameters. The first parameter represents the accumulated value of all the calculations so far, and the second parameter represents the current value in the array. The following example shows how to sum an array of numbers:

console.log([1,2,3,4,5].reduce( (acc,val) => acc + val ));
//> 15

The reduce() method also takes a second parameter after the callback, which is the initial value of the accumulator, acc. For example, we could total the numbers in an array, but starting at 10, insteal of zero:

console.log([1,2,3,4,5].reduce( (acc,val) => acc + val, 10 ));
//> 25

Lab 14. Calculating the average word length in a sentence that inputted by user (using prompt to input sentence).

Another example could be to calculate the average word length in a sentence:

const sentence = 'The quick brown for jumped over the lazy dog';

The sentence can be converted into an array using split() method:

const words = sentence.split(' '); // ["The", "quick", "brown", "for", "jumped", "over", "the", "lazy", "dog"]

Now we can use the reduce() function to calculate the total number of letters in the sentence, by starting the count at 0 and adding on the length of each word in each step:

const totalChars = words.reduce( (total, word) => total + word.length,0 );
//>36

And a simple division sum tells us the average word length:

const average = totalChars/words.length;

– filter()

The filter() method returns a new array that only contains items from the original array that return true when passed to the callback.

For example, we can filter an array of numbers to just the even numbers using the following code:

const numbers = [2, 7, 6, 5, 11, 23, 12];
const evens = numbers.filter( x => x % 2 === 0 );
console.log(evens);
// [2, 6, 12]

The filter() method provides a useful way to finding all the truthy values from an array:

const array = [0, 1, '0', false, true, 'hello'];
const result = array.filter(Boolean);
console.log(result);
//> [1, "0", true, "hello"]

To find all the falsy values, the following filter can be used:

const array = [0, 1, '0', false, true, 'hello'];
const result = array.filter( x => !x);
console.log(result);

This uses the not operator, ! to return the complement of a value’s boolean representation. This means that any falsy values will return true and be returned by the filter.

Chaining iterators together (p158)

For example, we can calculate the sum of square numbers using the map() method to square each number in the array and then chain the reduce() method on the end to add the results together:
const result = [1,2,3].map( x => x * x ).reduce( (acc, x) => acc + x );
console.log(result);
//> 14

Improving the mean() function (p159)

Lab 15. Improving the mean() function using a callback. Then:

– Applying to double all the numbers before calculating the mean.

– Applying to square all the numbers before calculating the mean.


Lab 16. Quiz Ninja Project (p161)
-----
Cập nhật: 28/10/2019
-----