Objeto Function ECMAScript (classe)

As funções do ECMAScript são na verdade objetos completamente funcionais.

Objeto (classe) Function

O que mais interessa no ECMAScript pode ser que as funções sejam objetos completamente funcionais.

A classe Function pode representar qualquer função definida pelo desenvolvedor.

A sintaxe para criar funções diretamente usando a classe Function é a seguinte:

var function_name = new function()arg1, arg2, ... , argN, function_body)

No formato acima, cada arg todos têm um parâmetro, o último parâmetro é o corpo da função (o código a ser executado). Esses parâmetros devem ser strings.

Lembre-se dessa função?

function sayHi(sName, sMessage) {
  alert("Hello " + sName + sMessage);
}

também pode ser definido assim:

var sayHi 
= 
new Function("sName", "sMessage", "alert("Hello " + sName + sMessage)");

Embora seja um pouco difícil de escrever devido às strings, isso ajuda a entender que as funções são apenas um tipo de referência, e seu comportamento é o mesmo que o de funções criadas explicitamente com Function.

Veja o exemplo a seguir:

function doAdd(iNum) {
  alert(iNum + 20);
}
function doAdd(iNum) {
  alert(iNum + 10);
}
doAdd(10);	//Saída "20"

Como você já sabe, a segunda função sobrescreve a primeira função, fazendo com que doAdd(10) gere "20" em vez de "30".

Se reescrevermos o bloco de código da seguinte forma, o conceito fica claro:

var doAdd = new Function("iNum", "alert(iNum + 20)");
var doAdd = new Function("iNum", "alert(iNum + 10)");
doAdd(10);

Observe este trecho de código, claramente, o valor de doAdd foi alterado para um ponteiro para um objeto diferente. O nome da função é apenas uma referência ao objeto da função, agindo como outros objetos. Até mesmo podemos fazer duas variáveis apontarem para a mesma função:

var doAdd = new Function("iNum", "alert(iNum + 10)");
var alsodoAdd = doAdd;
doAdd(10);	//Saída "20"
alsodoAdd(10);	//Saída "20"

Aqui, a variável doAdd é definida como uma função, e então alsodoAdd é declarada como um ponteiro que aponta para a mesma função. Ambos os variáveis podem executar o código da função e gerar o mesmo resultado - "20". Portanto, se o nome da função é apenas um ponteiro para a função, podemos passar a função como parâmetro para outra função? A resposta é afirmativa!

function callAnotherFunc(fnFunction, vArgument) {
  fnFunction(vArgument);
}
var doAdd = new Function("iNum", "alert(iNum + 10)");
callAnotherFunc(doAdd, 10); // Saída "20"

No exemplo acima, callAnotherFunc() tem dois parâmetros - a função a ser chamada e os parâmetros a serem passados para a função. Este código passa doAdd() para a função callAnotherFunc(), os parâmetros são 10, e a saída é "20".

Atenção:Embora seja possível criar funções usando o construtor Function, é melhor não usá-lo, pois definir funções com ele é muito mais lento do que usar métodos tradicionais. No entanto, todas as funções devem ser vistas como instâncias da classe Function.

Propriedade length do objeto Function

Como mencionado anteriormente, as funções pertencem ao tipo de referência, então elas também têm propriedades e métodos.

A propriedade length definida pelo ECMAScript declara o número de parâmetros esperados pela função. Por exemplo:

function doAdd(iNum) {
  alert(iNum + 10);
}
function sayHi() {
  alert("Hi");
}
alert(doAdd.length); // Saída "1"
alert(sayHi.length); // Saída "0"

A função doAdd() define um parâmetro, então seu length é 1; sayHi() não define parâmetros, então length é 0.

Lembre-se, independentemente de quantos parâmetros foram definidos, o ECMAScript pode aceitar um número arbitrário de parâmetros (até 25), isso foi explicado no capítulo 'Resumo de Funções'. A propriedade length é apenas uma maneira conveniente de verificar o número esperado de parâmetros em caso padrão.

Métodos do objeto Function

O objeto Function também possui os métodos valueOf() e toString() compartilhados com todos os objetos. Ambos os métodos retornam o código-fonte da função, especialmente úteis durante a depuração. Por exemplo:

function doAdd(iNum) {
  alert(iNum + 10);
}
document.write(doAdd.toString());

O código acima escreveu o texto da função doAdd().Experimente pessoalmente!