8. As funções

8.1. script [func-01]
O script analisa o modo de passagem dos parâmetros de uma função:
- passagem por valor para números, cadeias de caracteres e valores booleanos;
- passagem por referência para matrizes, objetos literais e funções;
'use strict';
// modo de passagem de parâmetros de uma função
// -----------------------número - passagem por valor
function doSomethingWithNumber(param) {
param++;
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === count);
}
// código de chamada
let count = 10;
doSomethingWithNumber(count);
console.log("[count outside function]=", count);
// --------------------- cadeia de caracteres - passagem por valor
function doSomethingWithString(param) {
param += " xyz"
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === text);
}
// código de chamada
let text = "abcd";
doSomethingWithString(text);
console.log("[text outside function]=", text);
// --------------------- booleano - passagem por valor
function doSomethingWithBoolean(param) {
param = !param;
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === bool);
}
// código de chamada
let bool = true;
doSomethingWithBoolean(bool);
console.log("bool [outside function]=", bool);
// --------------------- tabela - passagem por referência
function doSomethingWithArray(param) {
param.push(1000);
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === tab);
}
// código de chamada
const tab = [10, 20, 30];
doSomethingWithArray(tab);
console.log("[tab outside function]=", tab);
// --------------------- objeto - passagem por referência
function doSomethingWithObject(param) {
param.unePropriétéNouvelle = "xyz";
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === obj);
}
// código de chamada
const obj = [10, 20, 30];
doSomethingWithObject(obj);
console.log("[obj outside function]=", obj);
// --------------------- função - passagem por referência
function doSomethingWithFunction(param) {
// uma coisa um pouco estranha, mas que, no entanto, funciona
param.unePropriétéNouvelle = "xyz";
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === f);
}
// código de chamada
const f = x => x + 4;
doSomethingWithFunction(f);
console.log("[f outside function]=", f, f.unePropriétéNouvelle, typeof (f));
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-01.js"
[param inside function]= 11 [type]= number [passage par référence]= false
[count outside function]= 10
[param inside function]= abcd xyz [type]= string [passage par référence]= false
[text outside function]= abcd
[param inside function]= false [type]= boolean [passage par référence]= false
bool [outside function]= true
[param inside function]= [ 10, 20, 30, 1000 ] [type]= object [passage par référence]= true
[tab outside function]= [ 10, 20, 30, 1000 ]
[param inside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ] [type]= object [passage par référence]= true
[obj outside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ]
[param inside function]= x => x + 4 [type]= function [passage par référence]= true
[f outside function]= x => x + 4 xyz function
8.2. script [func-02]
O script seguinte mostra que o tipo [function] é um tipo de dados como qualquer outro e que uma variável pode ter esse tipo. Mostra também duas formas de definir uma função:
- uma com a palavra-chave [function];
- a outra com a notação «seta» =>;
''use strict';
// é possível atribuir uma função a uma variável
const variable1 = function (a, b) {
return a + b;
};
console.log("typeof(variable1)=", typeof (variable1));
// a variável pode depois ser utilizada como uma função
console.log("variable1(10,12)=", variable1(10, 12));
// a definição da função pode ser feita com a notação =>
const variable2 = (a, b, c) => {
return a - b + c;
};
console.log("variable2(10,12,14)=", variable2(10, 12, 14));
// pode-se omitir as chaves se houver apenas uma expressão no código da função
// essa expressão é, então, o valor de retorno da função
const variable3 = (a, b, c) => a + b + c;
console.log("variable3(10,12,14)=", variable3(10, 12, 14));
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-02.js"
typeof(variable1)= function
variable1(10,12)= 22
variable2(10,12,14)= 12
variable3(10,12,14)= 36
8.3. script [func-03]
Este script aborda a possibilidade de passar uma função como parâmetro para outra função. Este procedimento é amplamente utilizado nos frameworks JavaScript.
'use strict';
// os parâmetros de uma função podem ser do tipo [fonction]
// função f1
function f1(param1, param2) {
return param1 + param2 + 10;
}
// função f2
function f2(param1, param2) {
return param1 + param2 + 20;
}
// função g com a função f como parâmetro
function g(param1, param2, f) {
return f(param1, param2) + 100;
}
// utilizações de g
console.log(g(0, 10, f1));
console.log(g(0, 10, f2));
// o parâmetro efetivo do tipo função pode ser passado diretamente - forma 1
console.log(g(0, 10, (param1, param2) => {
return param1 + param2 + 30;
}));
// o parâmetro efetivo do tipo função pode ser passado diretamente - forma 2
console.log(g(0, 10, function (param1, param2) {
return param1 + param2 + 40;
}));
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-03.js"
120
130
140
150
8.4. script [func-04]
O script seguinte demonstra que uma função JavaScript pode comportar-se como uma classe:
'use strict';
// uma função pode ser utilizada como um objeto
// uma estrutura vazia
function f() {
}
// à qual são atribuídas propriedades a partir do exterior
f.prop1 = "val1";
f.show = function () {
console.log(this.prop1);
}
// utilização de f
f.show();
// uma função g que funciona como uma classe
function g() {
this.prop2 = "val2";
this.show = function () {
console.log(this.prop2);
}
}
// instanciação da função com [new]
new g().show();
Comentários
- linhas 5-7: o corpo da função f não define nenhuma propriedade;
- linhas 9-12: atribuem-se propriedades à função f a partir do exterior;
- linha 14: utilização da função (objeto) f. Note-se que não se escreve [f()], mas simplesmente [f]. Trata-se aqui da notação de um objeto;
- linhas 17-22: define-se uma função [g] como se fosse uma classe com propriedades e métodos;
- linha 24: a função [g] é instanciada por [new g()];
Resultados da execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2
A função ES6 introduziu o conceito de classe, o que nos permite agora evitar recorrer a funções para obter classes.
8.5. script [func-05]
O script [func-05] mostra a utilização de um operador denominado [rest operator]:
'use strict';
// operador resto
function f(arg1, ...otherArgs) {
// 1.º argumento
console.log("arg1=", arg1);
// os restantes argumentos
let i = 0;
otherArgs.forEach(element => {
console.log("otherArguments[", i, "]=", element);
i++;
});
}
// chamada
f(1, "deux", "trois", { x: 2, y: 3 })
- linha 3: a notação [...otherArgs] faz com que, com uma chamada do tipo f(param1, param2, param3), tenhamos a linha 3:
- arg1=param1
- otherArgs=[param2, param3]. [otherArgs] é, portanto, uma matriz que reúne todos os parâmetros efetivos passados para [param1];
Os resultados da aplicação são os seguintes: