Funções em JavaScript

Publicado: 15/11/2013 em Programação
Tags:

1. Introdução
São características das funções em JavaScript (JS):

  • serem objetos de primeira classe. Tratadas como qualquer outro objeto da linguagem, inclusive tendo propriedades e métodos próprios;
  • definem escopo;
  • poderem ser invocadas na forma de funções construtoras;
  • terem propriedades:
    • a propriedade “prototype” aponta para um novo objeto em branco, que por sua vez possui uma propriedade “constructor”. O “constructor” aponta para a função criada;
    • a propriedade “name” armazena o nome da função como uma string. Em funções sem nome, esta propriedade terá uma string vazia;
    • a propriedade “this”, que se refere a um objeto que está implicitamente associado à invocação da função e que recebe o nome de “contexto da função”. O parâmetro “this” aponta para algo que depende de como a função é invocada;
    • outras propriedade criadas pelo usuário, a qualquer tempo.

Funções em JS são declaradas utilizando um “literal de função” que cria um valor de função. Literais de função são compostos de quatro partes:

  • a palavera-chave “function”;
  • um nome, opcional (se omitido será uma “função anônima”) que, se especificado, deve ser um identificador JS válido;
  • uma lista separada por vírgulas de nomes de parâmetros entre parênteses;
  • o corpo da função, como uma série de instruções JS entre chaves.

OBS:
a) se não houver a necessidade de uma função ser chamada por seu nome, não há necessidade de dar um nome a ela (será uma função anônima);
b) quando uma função é nomeada, esse nome é válido ao longo do escopo dentro do qual a função é declarada.

Exemplos de declarações de funções:


function calcular() {return true;} // declaração de uma função nomeada
var xyz = function() {return true;} // declaração de uma função anônima atribuída a variável xyz

function fixar() {        // declaração de uma função nomeada
    var a = 0;
    return a;
}

var laranja = {
    cortar: function(){  // declaração de uma função anônima como método
        alert('cortou');
    }
};

setTimeout(
    function() { alert('fim temporização'); },   // declaração de uma função anônima como callback
    500);

2. Escopo
Em JS, escopos são declarados por “funções”, e não por blocos. Exemplo:

if (a) {
    var x = 10;
}
alert(x);

No exemplo acima, o JS não encerra o escopo da variável x ao final do bloco if. O escopo funciona da seguinte forma em JS:

  • declaração de variável está em escopo a partir do ponto de sua declaração até o final da função dentro da qual fora declarada;
  • função nomeada está em escopo dentro da função inteira na qual fora declarada (mecanismo de içamento, ou “hoisting”).

2.1 Parâmetro “this”
Sempre que uma função é invocada, além dos parâmetros que representam os argumentos que foram fornecidos na chamada da função, um parâmetro implícito chamado “this” também é transmitido a ela. O parâmetro “this” se refere a um objeto que está implicitamente associado à invocação da função e que recebe o nome de “contexto da função”. O parâmetro “this” aponta para algo que depende de como a função é invocada.

3. Invocações
Há 4 (quatro) maneiras diferentes de invocarmos uma função:

  • como uma função, na qual a função é invocada de modo direto;
  • como um método, o que associa a invocação a um objeto;
  • como um construtor, no qual um novo objeto é trazido à existência;
  • por meio de seus métodos apply() e call() (aplicação/chamada).

Todas as invocações de funções também recebem dois parâmetros implícitos: “arguments” e “this”. Eles podem ser referenciados dentro da função da mesma forma que qualquer outro parâmetro nomeado explicitamente.

3.1 Invocação como função
Ocorre quando uma função é invocada utilizando o operador () e a expressão para o qual o operador () é aplicado não referencia a função como uma propriedade de um objeto. Exemplos:

function calcular() {};
calcular();

var xyz = function() {};
xyz();

OBS: observe que o contexto da função será seu contexto externo, e o parâmetro this apontará para esse contexto externo à função.

3.2 Invocação como método
Ocorre quando uma função é atribuída a uma propriedade de um objeto e a invocação ocorre referenciado-se a função que utiliza essa propriedade. A função será invocada como um método desse objeto. Exemplo:


var xyz = {};
xyz.calcular = function() {};
xyz.calcular();

OBS:

  • observe que o contexto da função será o objeto, e o parâmetro this aponta para este objeto. Esta, junto com construtores, são as principais formas pelas quais o JS permite que códigos orientados a objetos sejam escritos;
  • notar que o contexto de funções para cada invocação da função muda dependendo de como ela é invocada, e não de acordo como foi declarada.

3.3 Invocação como construtor
Para invocar a função como um construtor, precedemos sua invocação com a palavra-chave “new”. Exemplo:

function Especialistas() {	// define um construtor que cria um a propriedade "oculto" em qualquer objeto que seja o contexto da função.
	this.ocultar = function() { return this;};
}
var especialista1 = new Especialistas();
var especialista2 = new Especialistas();
var contexto1 = especialista1.ocultar();
var contexto2 = especialista2.ocultar();

OBS: a codificação como construtor traz a característica de se evitar a repetição de código. O código comum é escrito uma só vez, como o corpo do cnstrutor.

4. O padrão de função imediata

O padrão de função imediata é uma sintaxe que permite executar uma função tão logo ela seja definida. Veja o exemplo:

(funtion () {
	alert('Olá');
}());

Cuidados com a sintaxe:

  • definir a função usando uma expressão de função;
  • adicionar um par de parênteses no final, o que faz a função ser executada imediatamente;
  • colcoar toda a função entre parênteses.

Outro exemplo:

var resultado = (function () {
	return 2 + 2;
}());	// resultado = 4

5. Herança e Funções Construtoras do Usuário
O JavaScript possui herança, podendo ser realizada de várias formas. A forma mais comum é através do uso de protótipos, onde um “protótipo” é um objeto. Toda função que é criada recebe automaticamente uma propriedade “prototype” que aponta para um novo objeto em branco. Por sua vez, este objeto tem uma propriedade “constructor” que aponta para a função que fora criada. E aqui está a mágica da herança: pode ser adicionado membros a esse objeto em branco e, quando se fizer a sua instanciação, estes outros objetos criados herdarão suas propriedades e métodos. Vejamos o caso prático a mostrado a seguir onde se faz a criação de um novo objeto através de uma função construtora, o que permite herdar o método identificar() do objeto original:

function Identificacao(p_name) {
	this.name = p_name;
};
Identificar.prototype.identificar = function () {
	return "Eu sou " + this.name;
};

Para utilizar esta função construtora, instanciando novos objetos:
var maria = new Identificacao("Maria");
maria.identificar(); // "Eu sou Maria"

OBS:
a) Construtores não deixam de ser funções, mas são invocados com new. “Identificacao” parece muito com uma classe, mas não há classes no JavaScript;
b) Adicionamos o método identificar() ao protótipo da função construtora Identificacao. Isso é mais eficiente que definir este método através de this, pois identificar() não se altera de uma instância para outra. Caso se utilizasse “this”, a cada nova chamada de “new Identificacao()” uma nova função identificar() seria criada desnecessariamente, não reaproveitando código. No exemplo acima, cada nova instância de Pessoa herda o método identificar() sem precisar fazer sua recriação.

Links:
Padrões de desenvolvimento JavaScript que utilizo

Deixe um comentário, pois isto é muito motivante para continuarmos este trabalho

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s