Como as funções de ordem superior, como .map (), funcionam internamente em JavaScript?

17

Atualmente, todo mundo tenta usar esse tipo de funções de ordem superior para obter resultados promissores ao escrever menos código. Mas eu me pergunto como essas funções funcionam internamente.

Suponha que se eu escrever algo como

var numbers = [16, 25, 36];
var results = numbers.map(Math.sqrt);
console.log(results); // [4, 5, 6]

Eu sei que cada elemento da matriz 'number' está repetindo um por um, mas como ?

Tentei procurá-lo, mas ainda não obtive resposta satisfatória.

Bilal Khan
fonte
10
Dê uma olhada no polyfil de Array.map
AZ_ 13/01
É uma função chamada mapque foi adicionada ao tipo Array. Esta função assume uma função como um parâmetro que é chamado durante o loop pelo array. Os valores de retorno das chamadas de função são retornados em uma matriz.
ssc-hrep3 13/01
O mapa funciona basicamente como foreach para iterar a matriz, significa que ela obterá todos os elementos da matriz, um por um, aplicando o comando / operação fornecido em cada elemento e enviando-o para a nova matriz.
Adnan Tariq

Respostas:

23

.mapé apenas um método que aceita um retorno de chamada, chama o retorno de chamada para cada item da matriz e atribui o valor a uma nova matriz. Não há nada de muito especial nisso. Você pode até implementá-lo facilmente:

Array.prototype.myMap = function(callback) {
  const newArr = [];
  for (let i = 0; i < this.length; i++) {
    newArr.push(callback(this[i], i, this));
  }
  return newArr;
}

var numbers = [16, 25, 36];
var results = numbers.myMap(Math.sqrt);
console.log(results); // [4, 5, 6]

Para ser totalmente compatível com as especificações, você também precisa verificar, entre outras coisas, se o thisobjeto callbacké passível de chamada e .callo retorno de chamada com o segundo parâmetro passado para myMapse houver um, mas esses detalhes não são importante para o entendimento inicial das funções de ordem superior.

CertainPerformance
fonte
8
Isso me lembra algumas outras respostas ...
Bergi 13/01
7

Eu acho que todo fornecedor deve implementá-lo de acordo com as especificações

A implementação real, por exemplo, a V8 pode ser um pouco complexa, consulte esta resposta para começar. Você também pode consultar a fonte v8 no github, mas pode não ser fácil entender apenas uma parte isoladamente.

Citado da resposta acima:

Desenvolvedor V8 aqui. Temos várias técnicas de implementação diferentes para "builtins": algumas são escritas em C ++, outras em Torque, outras no que chamamos de CodeStubAssembler e outras diretamente na montagem. Nas versões anteriores do V8, alguns foram implementados em JavaScript. Cada uma dessas estratégias possui seus próprios pontos fortes (troca da complexidade do código, depuração, desempenho em várias situações, tamanho binário e consumo de memória); Além disso, sempre há o motivo histórico pelo qual o código evoluiu ao longo do tempo.

Especificação do ES2015:

  1. Seja O como ToObject ( este valor).
  2. ReturnIfAbrupt ( O ).
  3. Seja len ToLength (Get ( O , "length")).
  4. ReturnIfAbrupt ( len ).
  5. Se IsCallable ( callbackfn ) for falso , lance uma exceção TypeError .
  6. Se thisArg foi fornecido, deixe- T ser thisArg ; então deixar T ser indefinido .
  7. Seja A ser ArraySpeciesCreate ( O , len ).
  8. ReturnIfAbrupt ( A ).
  9. Seja k 0.
  10. Repita, enquanto k < len
    1. Seja Pk o ToString ( k ).
    2. Seja kPresent seja HasProperty ( O , Pk ).
    3. ReturnIfAbrupt ( kPresent ).
    4. Se o kPresent for verdadeiro , então
      1. Seja kValue seja Get ( O , Pk ).
      2. ReturnIfAbrupt ( kValue ).
      3. Seja mappedValue seja Call ( callbackfn , T , « kValue , k , O »).
      4. ReturnIfAbrupt ( mappedValue ).
      5. Deixe o status ser CreateDataPropertyOrThrow ( A , Pk , mappedValue ).
      6. ReturnIfAbrupt ( status ).
    5. Aumente k em 1.
  11. Retorno A .
sabithpocker
fonte
2
Estou curioso, as especificações <li> list-style-typenão são copiáveis ​​no Chrome nem no FF. Você escreveu os números manualmente, ou está faltando um método melhor?
CertainPerformance
5
@CertainPerformance lol. Copie HTML da fonte, HTML para a ferramenta online de descontos.
sabithpocker 13/01