JavaScript Developer

segunda-feira, setembro 11, 2006

Funções com mais detalhes

Vamos hoje dar continuidade aos nossos estudos, hoje eu vou falar mais sobre escopo, vou falar sobre oque são objetos em JavaScript (calma, criação e implementação de objetos vai ficar pra outro dia, hoje vamos só entender o conceito do que é um objeto em JavaScript) e também vamos aprofundar o estudo de funções.

Antes de continuarmos eu gostaria de dizer que eu não estou tentando ensinar lógica de programação, esses artigos são voltados a pessoas que já sabem lógica de programação, oque eu pretendo passar aqui é como usar a linguagem JavaScript.

Escopo e Objetos, a relação existente
No artigo passado nós vimos um pouco sobre o escopo das variáveis, vimos a diferença entre uma variável global e uma variável criada internamente para uma função, agora vamos entender melhor oque realmente acontece.

Em JavaScript, praticamente tudo (apenas com a excessão de tipos primitivos) são objetos, isso mesmo, uma string é um objeto, um array(falaremos sobre arrays em outros artigos) é um objeto, até mesmo uma função é um objeto no JavaScript.

Os escopos sempre são relativos aos objetos, para uma variável existir, ela tem que estar dentro de um objeto, e esse objeto é o seu escopo, como eu disse antes, o escopo global é o objeto window, quando você declara uma var dentro de uma função, você está criando uma variável no escopo daquela função, mais a frente ainda nesse artigo eu mostrarei outras formas de criar funções, e vocês verão que uma função pode ser tratada da mesma forma que uma variável.

Com isso eu termino minha explicação sobre escopo, mas a melhor forma de realmente entender isso é fazendo na prática, eu recomendo que vocês façam testes pra ver oque acontece com uma variável em diferentes escopos, porque essa é a melhor forma de enteder isso.

Funções, conhecendo-as melhor
Nós ja aprendemos a criar funções, a passar parâmetros para a mesma e também como retornar dados, hoje vamos explorar melhor o conceito de funções em JavaScript e também vamos aprender a usar mais recurso das funções em JavaScript.

Primeiro eu quero que fique bem claro para todos: "Funções de JavaScript são objetos".
Exatamente, pra quem entender de oop, eu poderia dizer que a propria função do javascript já contem seus métodos e variáveis internas, ela realmente é um objeto e deve ser tratada como tal, vamos ver uma outra forma de criar uma função, usando essa forma fica mais claro o conceito de que ela é um objeto:

var minhaFuncao = function() {
alert('funcao criada com sintaxe de variavel');
};

minhaFuncao();


Como podemos ver, essa sintaxe parece que estamos criando uma variável, mas estamos criando uma função. Optar por usar esse modo ou o outro que vimos anteriormente é uma questão de gosto, mas existe casos que só é possivel criar dessa 2 forma, eu sinceramente prefiro essa sintaxe mostrada acima, pois nela temos uma melhor controle sobre qual escopo a função está sendo criada.

obs: note que quando usamos essa sintaxe, colocamos um ponto e vírgula (;) após a criação dela, essa é a sintaxe correta, pois estamos declarando uma variável, e sempre depois de uma declaração tem que vir um ponto e vírgula.

As vezes nós criamos uma função sobre um escopo, mas precisamos que ela seja executada sobre um escopo diferente, entao como fazer isso? Como mudar o escopo da função?

Em JavaScript isso é facil, como eu disse, funções são objetos, e elas tem seus métodos, uma função pode ser chamada de 3 formas diferentes, vamos ve-las:

var soma = function(a, b) {
var resultado = a + b;
alert('Resultado da soma: ' + resultado);
};

soma(2, 3); //essa é a forma que estamos usando, apenas diz o nome da funcao e acresce de ()
soma.call(this, 2, 3); //esse é outro modo de chamar a função
soma.apply(this, [2, 3]); //e temos também esse terceiro


Vamos agora entender a diferença entre esses 3 modos:

soma(2, 3) => esse é o método padrão, a função será executada no escopo de onde ela foi chamada, e os argumentos são passados normalmente.

soma.call(this, 2, 3) => esse é muito parecido com o padrão, dizemos o nome da função e chamados o método call da mesma, a única diferença se dá no primeiro argumento, o primeiro argumento não será passado, ao invéz disso, o primeiro argumento informa em qual escopo a função deve ser executada, usando this mandamos executar no escopo atual, e nesse caso não existe diferença entre esse modo e o padrão.

soma.apply(this, [2, 3]) => esse quase igual ao anterior, o primeiro argumento funciona da mesma forma (para expecificar o escopo) mas temos diferenca na hora de passar os argumentos para a função. No lugar de passar os argumentos separados por vírgula, oque passamos é um array contendo todos os argumentos, essa forma é mais dinâmica que as outras.

obs: quando usamos [] estamos nos referindo a arrays, vamos entender isso melhor em futuros artigos.

Vamos agora aprender a usar parâmetros não definidos nas funções.
Imagine que você queria uma função que some todos os parâmetros que forem passados para a mesma, mas você não sabe quantos parâmetros serão passados para essa função, para resolver esse problema, usaremos uma variável que é definida internamente pelo objeto da função, a variável arguments.

A variável arguments é definida automaticamente em qualquer função, ela é um array que contém todos os parâmetros passados para a função, vamos criar nossa função que soma todos os argumentos passados, assim veremos seu uso:

var somaTudo = function() {
var total = 0; //iniciando a variavel que vai guardar o valor das somas

for(var i = 0; i < arguments.length; i++) {
total += arguments[i]; //adicionando valor na variavel total
}

return total;
};

alert(somaTudo(3, 2, 4, 8));
alert(somaTudo(4, 5, 1, 3, 9, 6, 13));
alert(somaTudo());
alert(somaTudo(10));
alert(somaTudo(3, 2, 1, 5, 6, 7));


Viram como é simples o uso da variável arguments?

Para finalizar, vou deixar aqui uma referência (em inglês) do objeto Function, assim vocês podem ir testando seus métodos e variáveis, e lembrem-se sempre, a melhor maneira de aprender é fazendo, façam testes por ai, eu não tive tempo pra passar exercícios, mas futuramente eu estarei passando exercícios para vocês tentarem resolver, segue a referência:

Function (Built-in Object)
Function is the object from which JavaScript functions are derived. Functions are first-class data types in JavaScript, so they may be assigned to variables and passed to functions as you would any other piece of data. Functions are, of course, reference types.

The Function object provides both static properties like length and properties that convey useful information during the execution of the function, for example, the arguments[] array.

Constructor
var instanceName = new Function([arg1 [, arg2 [, ...]] ,] body);

The body parameter is a string containing the text that makes up the body of the function. The optional argN’s are the names of the formal parameters the function accepts. For example:

var myAdd = new Function("x", "y", "return x + y");
var sum = myAdd(17, 34);

Properties
arguments[] An implicitly filled and implicitly available (directly usable as "arguments" from within the function) array of parameters that were passed to the function. This value is null if the function is not currently executing. (IE4+ (JScript 2.0+), MOZ, N3+ (JavaScript 1.1+), ECMA Edition 1)

arguments.callee Reference to the current function. This property is deprecated. (N4+, MOZ, IE5.5+)

arguments.caller Reference to the function that invoked the current function. This property is deprecated. (N3, IE4+)

arguments.length The number of arguments that were passed to the function. (IE4+ (JScript 2.0+), MOZ, N3+ (JavaScript 1.1+), ECMA Edition 1)

arity Numeric value indicating how many arguments the function expects. This property is deprecated. (N4+, MOZ)

caller Reference to the function that invoked the current function or null if called from the global context. (IE4+ (JScript 2.0+), MOZ, N3+)

constructor Reference to the constructor object that created the object. (IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), ECMA Edition 1)

length The number of arguments the function expects to be passed. (IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), ECMA Edition 1)

prototype Reference to the object’s prototype. (IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), ECMA Edition 1)

Methods
apply(thisArg [, argArray]) Invokes the function with the object referenced by thisArg as its context (so references to this in the function reference thisArg). The optional parameter argArray contains the list of parameters to pass to the function as it is invoked. (IE5.5+ (JScript 5.5+), N4.06+ (JavaScript 1.3+), MOZ, ECMA Edition 3)

call(thisArg [, arg1 [, arg2 [, ...]]]) Invokes the function with the object referenced by thisArg as its context (so references to this in the function reference thisArg). The optional parameters argN are passed to the function as it is invoked. (IE5.5+ (JScript 5.5+), N4.06+ (JavaScript 1.3+), MOZ, ECMA Edition 3)

toString() Returns the string version of the function source. The body of built-in and browser objects will typically be represented by the value "[native code]". (IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), MOZ, ECMA Edition 1)

valueOf() Returns the string version of the function source. The body of built-in and browser objects will typically be represented by the value "[native code]". (IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), MOZ, ECMA Edition 1)

Support
Supported in IE4+ (JScript 2.0+), N3+ (JavaScript 1.1+), MOZ, ECMAScript Edition 1.


Por hoje é tudo, no próximo artigos falaremos sobre estruturas de controle e objetos, com isso iremos finalizar o "core" do JavaScript, e depois começaremos a falar dos objetos Built-In (Array, Date, String...).

Grato a atenção de todos.

1 Comments:

  • opa, gostei da terceira forma, essa eu não conhecia.
    tche, como eu faria uma função que concatenasse funções, ou seja:

    var cnt = function(func1, func2){
    return function(){
    func1();
    func2();
    }
    }

    window.onload = cnt(window.onload, jsInit);

    neste caso eu adicionaria uma função ao onload sem mecher em seu conteudo, mas se eu quizesse passar um array de funções p/ essa função, como eu faria funcao cnt()?

    By Blogger Wilian Fiabani [conhecimento sem limites], at 3:25 PM  

Postar um comentário

<< Home