¿Cómo funcionan las funciones de orden superior, como .map (), funcionan internamente en JavaScript?

17

Hoy en día, todos intentan utilizar este tipo de funciones de orden superior para obtener resultados prometedores al escribir menos código. Pero me pregunto cómo funcionan estas funciones internamente.

Supongamos que si escribo algo como

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

Sé que cada elemento de la matriz 'número' está iterando uno por uno, pero ¿cómo ?

Traté de buscarlo, pero aún no obtuve ninguna respuesta satisfactoria.

Bilal Khan
fuente
10
Echa un vistazo a polyfil de Array.map
AZ_
Es una función llamada mapque se agregó al tipo Array. Esta función toma una función como parámetro que luego se llama mientras recorre la matriz. Los valores de retorno de las llamadas a funciones se devuelven en una matriz.
ssc-hrep3
El mapa básicamente funciona como foreach para iterar la matriz, lo que significa que obtendrá todos los elementos de la matriz uno por uno y luego aplicará el comando / operación dado en cada elemento y luego lo insertará en una nueva matriz.
Adnan Tariq

Respuestas:

23

.mapes solo un método que acepta una devolución de llamada, invoca la devolución de llamada para cada elemento de la matriz y asigna el valor a una nueva matriz. No hay nada muy especial al respecto. Incluso puede implementarlo usted mismo con bastante facilidad:

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 cumplir con todas las especificaciones, también debe verificar, entre otras cosas, que thises un objeto, que callbackes invocable y .callla devolución de llamada con el segundo parámetro pasado myMapsi hay uno, pero esos son detalles que no importante para una comprensión inicial de las funciones de orden superior.

Cierto rendimiento
fuente
8
Esto me recuerda algunas otras respuestas ...
Bergi
7

Supongo que se supone que cada proveedor lo implemente según las especificaciones

La implementación real, por ejemplo V8 puede ser un poco compleja, consulte esta respuesta para comenzar. También puede referirse a la fuente v8 en github pero puede que no sea fácil entender solo una parte aisladamente.

Citado de la respuesta anterior:

Desarrollador V8 aquí. Tenemos varias técnicas de implementación diferentes para "builtins": algunas están escritas en C ++, otras en Torque, algunas en lo que llamamos CodeStubAssembler y algunas directamente en ensamblador. En versiones anteriores de V8, algunas se implementaron en JavaScript. Cada una de estas estrategias tiene sus propios puntos fuertes (compensando la complejidad del código, la depuración, el rendimiento en diversas situaciones, el tamaño binario y el consumo de memoria); Además, siempre existe la razón histórica de que el código haya evolucionado con el tiempo.

Especificación ES2015:

  1. Deje O ser ToObject ( este valor).
  2. ReturnIfAbrupt ( O ).
  3. Deje que len sea ​​ToLength (Get ( O , "length")).
  4. ReturnIfAbrupt ( len ).
  5. Si IsCallable ( callbackfn ) es falso , arroje una excepción TypeError .
  6. Si se proporcionó thisArg , deje que T sea thisArg ; de lo contrario, deje que T sea indefinido .
  7. Deje A ser ArraySpeciesCreate ( O , len ).
  8. ReturnIfAbrupt ( A ).
  9. Deje k ser 0.
  10. Repita, mientras k < len
    1. Deje que Pk sea ​​ToString ( k ).
    2. Deje kPresent ser HasProperty ( O , Pk ).
    3. ReturnIfAbrupt ( kPresent ).
    4. Si kPresent es verdadero , entonces
      1. Deje kValue ser Get ( O , Pk ).
      2. ReturnIfAbrupt ( kValue ).
      3. Deje que mappedValue sea ​​Call ( callbackfn , T , « kValue , k , O »).
      4. ReturnIfAbrupt ( mappedValue ).
      5. Deje que el estado sea ​​CreateDataPropertyOrThrow ( A , Pk , mappedValue ).
      6. ReturnIfAbrupt ( estado ).
    5. Aumenta k en 1.
  11. Volver A .
sabithpocker
fuente
2
Tengo curiosidad, las especificaciones <li> list-style-typeno se pueden copiar en Chrome ni FF. ¿Escribiste los números manualmente o hay un método mejor que me falta?
CertainPerformance
55
@CertainPerformance lol. Copie HTML desde la fuente, HTML a la herramienta en línea de descuento.
sabithpocker