Functions


A function is like a machine that recives some input, does something with it and returns something else.
So something new, created from the data that we've put in.

    Functions
    1) Uma função se comporta como qualquer outro objeto.
    2) Podemos armazenar funções em uma variável.
    3) Podemos passar uma função como um argumento para outra função.
    4) We can return a function from a function.

    • Tipos de Funções
      1) Função construtora
      Aquela que é um objeto construtor, por exemplo:
      var Person = function (name, yearOfBirth){
        this.name = name;
        this.yearOfBirth = yearOfBirth;
      }
      var jessica = new Person('jessica', 1969); objeto instânciado

      2) Anonymous Function
      Função sem nome, que não será acessada de outros lugares.
      Exemplo: return function(name){ ... }

      3) Callback Function
      Função que é chamada por outra função, pois foi passada a ela.
      Exempo: function arrayCalc(arr, fn) { fn é o parâmetro que receberá uma função e a chamará, portanto vai existir uma função que será chamada por outra função.
        ...
      }

      4) Immediately Invoked Functions (IIFE)
      Função que se chama, podem ser utilizadas para "data privacy", visto as variáveis criadas dentro dela que não serão acessíveis fora de seu escopo e portanto não afetarão o resto do código.

      5) Closures
      Clousure é quando você pode utilizar as variáveis de uma função que retornou outra função, a partir da função retornada, mesmo que a execução da principal já tenha sido finalizada.
      "An inner function has always access to the variables and parameters of its outer function, even after the outer function has returned".

    • Function Declaration
      a) Functions can call other functions,.
      b) Sintaxe:
      function functionName (argument, argument, argument, ...){
        function block (código a executar)
      }

    • Function Statements and Expressions
      Uma expressão em JS é quando realizamos algo com a função (function, if statments, while loops), onde recebe-se um retorno.
      Por exemplo, passar um parâmetro para a função e receber uma resposta, passar 2+2 e receber 4, escrever um if e receber um retorno, como um console.log.

    • Passing Functions as Arguments

      var years = [1990, 1965, 1937, 2005, 1998];

      function arrayCalc(arr, fn) { arr = recebe o array por argumento com os dados, fn = function com os métodos
      var arrRes = []; Criado um novo array vazio, que irá ser preenchido com os resultados da função e retornado como o resultado dessa função.
      for (var i = 0; i < arr.lenght; i++) {
      The result of the following array will be result of calling the fn function, and then we pass the current element of our input array into this function.
      arrRes.push(fn(arr[i])); push = inserts element at the end of the array (will be the result of the array)
      }
      return arrRes;
      }

      //Callback functions: functions that we pass into functions that will them call them later.
      function calculateAge(el) { el = element | Function que só retorna a idade.
      return 2019 - el; el = element = yearOfBirth
      }

      function isFullAge(el) {
      return el >= 18;
      }

      var ages = arrayCalc(years, calculateAge); Passa-se o years como array com informações a serem utilizadas pelo for e calculateAge como função a ser executada.
      var fullAges = arrayCalc(ages, isFullAge); Passa-se o resultado do array ages, que contém as idades e a função isFullAge para ser executada.


      console.log(ages);
      console.log(fullAges);

    • Functions returning Functions
      function interviewQuestion(job) {
      if(job === 'lawyer') {
        return function(name) {
        console.log(name + ', what have you done in the past year to train your legal skills?');
       }
      } else if (job === 'secretary') {
        console.log(name + ', were you a Legal Secretary?');
       } else {
         return function(name) {
         console.log('Hello ' + name + ', what do you do?');
        }
       }
      }

      1) Lembrando que return function... irá retornar uma function inteira.
      var lawyerQuestion = interviewQuestion('lawyer');

      2) Agora dentro do teacherQuestion temos uma função, então podemos chama-la diretamente assim:
      lawyerQuestion('Mike');
      Retorno: Mike, what have you done in the past year to train your legal skills?
      Visto que foi retornada a função do job lawyer.

      ou
      interviewQuestion('lawyer')('Harvey');
      Visto que lê-se da esquerda para a direita, será retornado a função do job Lawyer e então será passado o nome Harvey para essa função que foi retornada.

    • Immediately Invoked Functions (IIFE)
      a) Função que se chama.
      b) Podem ser utilizadas para "data privacy", visto as variáveis criadas dentro dela que não serão acessíveis fora de seu escopo e portanto não afetarão o resto do código.
      c) Portanto não são utilizadas para criar um código que será reutilizado, será somente para data privacy.

      Sem passar argumentos
      (function () {
       var score = Math.random() * 10;
       console.log(score >= 5); retorna true ou false. Valor do score não é acessível fora da função, por causa do escopo.
      })();

      Passando argumentos para a função
      (function (goodluck) {
       var score = Math.random() * 10;
       console.log(score >= 5 - goodluck);
      })(5);

    • Closures
      1) Clousure é quando você pode utilizar as variáveis de uma função que retornou outra função, a partir da função retornada, mesmo que a execução da principal já tenha sido finalizada.
      2) Mesmo quando ela retornar, o objeto que foi criado com as variables vai ficar acessível.

      1) Start by calling the retirement function and passing the value of 66.
      2) The function then declares the 'a' variable and returns the function on the return.
      3) Then the function retirement finishes and it's execution context gets popped off the stack.
      4) Com isso, a função de retorno está armazenada no retirementUS.
      5) Agora começa o Closure, visto que agora vamos executar a função retirementUS(1990), mas veja que ela precisa da informação das variáveis retirementAge e 'a', que já saíram do execution context.
      6) Com isso, essa função irá conseguir utizar essas variáveis de uma função que já retornou.
      7) Closure é o fato dessas variáveis ainda estarem disponíveis para serem utilizadas, mesmo que a função já tenha finalizado.
      8) "An inner function has always access to the variables and parameters of its outer function, even after the outer function has returned".

      Exemplo 01
      function retirement(retirementAge) {
      //A variável a serve somente como string para completar a frase de retorno com a idade que a pessoa precisa ter para poder aposentar
       var a = ' years left until retirement.';
      //retorna uma function com quantos anos flta para o retirement
       return function(yearOfBirth) {
        var age = 2019 - yearOfBirth;
        console.log((retirementAge - age) + a);
       }
      }

      var retirementUS = retirement(66);
      var retirementGermany = retirement(65);
      var retirementIceland = retirement(67);

      retirementUS(1990);
      retirementGermany(1990);
      retirementIceland(1990);

      Exemplo 02

      function interview(job){
       return function(name){
        if(job === 'lawyer'){
        console.log(name + ' please, tell me about why you want to be a lawyer.');
        } else if (job === 'designer'){
         console.log(name + ' can you please show me your designs');
        } else {
        console.log('We don\'t have that job available');
       }
       }
      }

      interview('lawyer')('Jessica');

    • Bind, call and apply
      var jessica = {
      name: 'Jessica Pearson',
      timeOfCompany: 23,
      job: 'Lawyer',
      position: 'Managing Partner',
      presentation: function(style, timeOfDay) {
      if(style === 'formal') {
      console.log('Good ' + timeOfDay + ', ladies and gentlemen. My name is ' + this.name + '. I am a ' + this.job + ' working as a ' + this.position + ' at Pearson Hardman. I have been here for ' + this.timeOfCompany + ' years.');
      } else if(style === 'friendly') {
      console.log('Good ' + timeOfDay + ', my name is ' + this.name + ' and I am a ' + this.position + ' here at Pearson Hardman. I have been here for ' + this.timeOfCompany + ' years.');
      }
      }
      };

      var donna = {
      name: 'Donna',
      timeOfCompany: 15,
      job: 'Secretary',
      position: 'Legal Secretary'
      };

      jessica.presentation('formal', 'morning');
      jessica.presentation.call(donna, 'friendly', 'afternoon');
      //jessica.presentation.apply(donna, ['friendly', 'afternoon']); esse não funcionaria pois nossa função não espera receber um array

      Call
      a) Sintaxe: objetoQuePossuiFunçãoDesejada.nomeFunction.call(nomeObjetoASerUtilizado, argumentos);
      b) Exemplo: jessica.presentation.call(donna, 'friendly', 'afternoon');)
      Aqui temos que a função presentation do objeto jessica será chamada com os dados do objeto donna, pois o primeiro argumento que se passa após chamar a função call é a this variable, ou seja, qual objeto será o "this", ou qual objeto será o selecionado.

      Apply
      a) Sintaxe:
      b) Exemplo: jessica.presentation.apply(donna, ['friendly', 'afternoon']);
      Apply possui o mesmo uso do Call, porém retorna um array.

      Bind
      a) O que ele faz também pode ser chamado de Carrying, quando criamos uma função baseada em uma outra função, mas como alguns preset parameters.
      b) A diferença entre Bind e os outros é que Bind não imediatamente chama a função, ele gera uma cópia dela, podendo ser armazenada em algum lugar.
      c) Isso é útil para criarmos funções com preset arguments, ou seja, em que um dos argumentos é pré-definido, para não precisar defini-lo toda hora.
      d) Veja abaixo como é útil poder retornar a função do objeto jessica e pré definir um parâmetro.

      Exemplo 01
      var jessicaFriendly = Variável que armazena a função copiada pelo Bind.
      jessica.presentation.bind(jessica, 'formal'); Defindo que vamos utilizar as informações do objeto Jessica. Fixado 'Formal' como primeiro parâmetro.

      jessicaFriendly('morning'); Agora somente precisamos chamar essa função e definir o segundo parâmetro.
      jessicaFriendly('afternoon');
      jessicaFriendly('night');

      Exemplo 02 - Aplicação Real
      var years = [1990, 1965, 1937, 2005, 2000];

      function arrayCalc(arr, fn) { arr = array (will be years array), fn = function that we will passs that does the calcculations
      //Creates new empty array that will be filled and returned
        var arrRes = [];
       for (var i = 0; i < arr.length; i++) {
      The result of the following array will be result of calling the fn function, and then we pass the current element of our input array into this function
      arrRes.push(fn(arr[i])); push = inserts element at the end of the array (will be the result of the array)
      }
      return arrRes;
      }

      function calculateAge(el) {
      return 2019 - el;
      }

      function isFullAge(limit, el) {
      return el>= limit;
      }

      var ages = arrayCalc(years, calculateAge);
      var fullJapan = arrayCalc(ages, isFullAge.bind(this, 20));
      console.log(ages);
      console.log(fullJapan);

      Importante: a função Bind irá fixar um argumento, então ela é utilizada para fixar o limit, na Function isFullAge, e então a "substitui" por sua cópia, que somente irá receber um parâmetro, o el, que será o ages do array. Esse el é comparado com o limit fixado pela Bind, de 20.

      1) Passar a função isFullAge com o limit fixado, para que então o for possa rodar e colocar somente as idades nessa function, analisando se o el (age) é >= limit (fixado) ou não.
      2) O this é fixo, o 20 é o primeiro argumento a ser passado, ou seja, o que será fixado.

      Coding Challenge - Questions Quiz

      Normal Quiz



      Expert Quiz