8. Las funciones

8.1. script [func-01]
El script examina cómo se pasan los parámetros a una función:
- pass-by-value para números, cadenas y booleanos;
- paso por referencia para matrices, objetos literales y funciones;
1. 'use strict';
2. // function parameter passing modes
3. // -----------------------number - passed by value
4. function doSomethingWithNumber(param) {
5. param++;
6. console.log("[param inside function]=", param, "[type]=", typeof(param), "[passed by reference]=", param === count);
7. }
8. // call code
9. let count = 10;
10. doSomethingWithNumber(count);
11. console.log("[count outside function]=", count);
12.
13. // --------------------- string - passed by value
14. function doSomethingWithString(param) {
15. param += " xyz"
16. console.log("[param inside function]=", param, "[type]=", typeof (param), "[pass-by-reference]=", param === text);
17. }
18. // call code
19. let text = "abcd";
20. doSomethingWithString(text);
21. console.log("[text outside function]=", text);
22.
23. // --------------------- boolean - passed by value
24. function doSomethingWithBoolean(param) {
25. param = !param;
26. console.log("[param inside function]=", param, "[type]=", typeof (param), "[pass-by-reference]=", param === bool);
27. }
28. // call code
29. let bool = true;
30. doSomethingWithBoolean(bool);
31. console.log("bool [outside function]=", bool);
32.
33. // --------------------- array - passed by reference
34. function doSomethingWithArray(param) {
35. param.push(1000);
36. console.log("[param inside function]=", param, "[type]=", typeof (param), "[pass-by-reference]=", param === tab);
37. }
38. // calling code
39. const tab = [10, 20, 30];
40. doSomethingWithArray(tab);
41. console.log("[tab outside function]=", tab);
42.
43. // --------------------- object - passed by reference
44. function doSomethingWithObject(param) {
45. param.newProperty = "xyz";
46. console.log("[param inside function]=", param, "[type]=", typeof (param), "[pass-by-reference]=", param === obj);
47. }
48. // calling code
49. const obj = [10, 20, 30];
50. doSomethingWithObject(obj);
51. console.log("[obj outside function]=", obj);
52.
53. // --------------------- function - passed by reference
54. function doSomethingWithFunction(param) {
55. // something rather odd, but it works
56. param.newProperty = "xyz";
57. console.log("[param inside function]=", param, "[type]=", typeof (param), "[pass-by-reference]=", param === f);
58. }
59. // calling code
60. const f = x => x + 4;
61. doSomethingWithFunction(f);
62. console.log("[f outside function]=", f, f.newProperty, typeof (f));
Ejecución
1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\functions\func-01.js"
2. [param inside function]= 11 [type]= number [pass by reference]= false
3. [count outside function]= 10
4. [param inside function]= abcd xyz [type]= string [pass by reference]= false
5. [text outside function]= abcd
6. [param inside function]= false [type]= boolean [pass by reference]= false
7. bool [outside function]= true
8. [param inside function]= [ 10, 20, 30, 1000 ] [type]= object [pass by reference]= true
9. [tab outside function]= [ 10, 20, 30, 1000 ]
10. [param inside function]= [ 10, 20, 30, 'aNewProperty': 'xyz' ] [type]= object [pass by reference]= true
11. [obj outside function]= [ 10, 20, 30, 'aNewProperty': 'xyz' ]
12. [param inside function] = x => x + 4 [type] = function [pass by reference] = true
13. [f outside function] = x => x + 4 xyz function
8.2. script [func-02]
El siguiente script muestra que el tipo [función] es un tipo de dato como cualquier otro y que una variable puede tener este tipo. También muestra dos formas de definir una función:
- uno utilizando la [función] palabra clave;
- el otro utilizando la "flecha" notación =>;
1. 'use strict';
2. // you can assign a function to a variable
3. const variable1 = function (a, b) {
4. return a + b;
5. };
6. console.log("typeof(variable1)=", typeof (variable1));
7. // The variable can then be used as a function
8. console.log("variable1(10,12)=", variable1(10, 12));
9. // the function can be defined using the => syntax
10. const variable2 = (a, b, c) => {
11. return a - b + c;
12. };
13. console.log("variable2(10,12,14)=", variable2(10, 12, 14));
14. // You can omit the curly braces if there is only one expression in the function body
15. // this expression is then the function's return value
16. const variable3 = (a, b, c) => a + b + c;
17. console.log("variable3(10,12,14)=", variable3(10, 12, 14));
Ejecución
1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-02.js"
2. typeof(variable1) = function
3. variable1(10,12) = 22
4. variable2(10,12,14) = 12
5. variable3(10,12,14) = 36
8.3. script [func-03]
Este script demuestra la capacidad de pasar una función como parámetro a otra función. Esta técnica es ampliamente utilizada en frameworks JavaScript.
1. 'use strict';
2. // a function's parameters can be of type [function]
3.
4. // function f1
5. function f1(param1, param2) {
6. return param1 + param2 + 10;
7. }
8. // function f2
9. function f2(param1, param2) {
10. return param1 + param2 + 20;
11. }
12. // function g with function f as a parameter
13. function g(param1, param2, f) {
14. return f(param1, param2) + 100;
15. }
16. // uses of g
17. console.log(g(0, 10, f1));
18. console.log(g(0, 10, f2));
19. // the actual function parameter can be passed directly - form 1
20. console.log(g(0, 10, (param1, param2) => {
21. return param1 + param2 + 30;
22. }));
23. // the actual function-type parameter can be passed directly - form 2
24. console.log(g(0, 10, function (param1, param2) {
25. return param1 + param2 + 40;
26. }));
Ejecución
1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\functions\func-03.js"
2. 120
3. 130
4. 140
5. 150
8.4. script [func-04]
El siguiente script demuestra que una función JavaScript puede comportarse como una clase:
1. 'use strict';
2. // A function can be used as an object
3.
4. // an empty shell
5. function f() {
6.
7. }
8. // to which properties are assigned from the outside
9. f.prop1 = "val1";
10. f.show = function () {
11. console.log(this.prop1);
12. }
13. // using f
14. f.show();
15.
16. // a function g acting as a class
17. function g() {
18. this.prop2 = "val2";
19. this.show = function () {
20. console.log(this.prop2);
21. }
22. }
23. // Instantiate the function with [new]
24. new g().show();
Comentarios
- líneas 5-7: el cuerpo de la función f no define ninguna propiedad;
- líneas 9-12: se asignan propiedades a la función f desde fuera;
- línea 14: uso de la función (objeto) f. Observa que no escribimos [f()] sino simplemente [f]. Esta es la notación para un objeto;
- líneas 17-22: definimos una función [g] como si fuera una clase con propiedades y métodos;
- línea 24: la función [g] es instanciada por [new g()];
Resultados de la ejecución
1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
2. val1
3. val2
ES6 introdujo el concepto de clases, que ahora nos permite evitar el uso de funciones para crear clases.
8.5. script [func-05]
El script [func-05] demuestra el uso de un operador llamado [operador rest]:
1. 'use strict';
2. // rest operator
3. function f(arg1, ...otherArgs) {
4. // 1st argument
5. console.log("arg1=", arg1);
6. // the other arguments
7. let i = 0;
8. otherArgs.forEach(element => {
9. console.log("otherArguments[", i, "]=", element);
10. i++;
11. });
12. }
13.
14. // call
15. f(1, "two", "three", { x: 2, y: 3 })
- línea 3: la notación [...otherArgs] significa que con una llamada de la forma f(param1, param2, param3), tendremos la línea 3:
- arg1=param1
- otrosArgs = [param2, param3]. [otherArgs] es por tanto un array que recoge todos los parámetros reales pasados después de [param1];
Los resultados de la aplicación son los siguientes: