Převedení metod na samostatné funkce v JavaScriptu
Jen krátký tip na převedení metod (funkcí v prototype
) na samostané funkce v JS pomocí Proxy
(MDN).
Myšlenka stojí na možnosti použití Function.prototype.call() a Function.prototype.bind().
1
2
3
4
5
6
7
8
9
const arr= "ABCDEF".split("");//jen vytvoření pole
//#1
arr.forEach(conslole.log);
//#2
const forEach1= Array.prototype.forEach;
forEach1.call(arr, console.log);
//#3
const forEach= Function.prototype.call.bind(Array.prototype.forEach);
forEach(arr, console.log)
Ekvivalentí volání metody forEach
(body #1–#3). Ve #3 využijeme .bind
pro možnost volání bez .call
(šlo by také použít obalení funkcí).
Pro zobecnění a zautomatizování lze pomocí Proxy
vytvořit pomocné jmenné prostory či pomocnou funkci:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const utils= (function(proxy){
return {
Array: new Proxy(Array.prototype, proxy),
String: new Proxy(String.prototype, proxy),
console: new Proxy(console, { get(target,name){ return target[name].bind(target); } })
};
})({
get(target,name){ return Function.prototype.call.bind(target[name]); }
});
const { map }= utils.Array;
const { charCodeAt }= utils.String;
const { log }= utils.console;
log(map(["A"], a=> charCodeAt(a, 0)));
Použití jako jmenné prostory (tj. vytvoření knihovny)
1
2
3
4
5
6
7
8
9
const toFunctional= object=> object.prototype ?
new Proxy(object.prototype, { get(target,name){ return Function.prototype.call.bind(target[name]); } }) :
new Proxy(object, { get(target, name){ return target[name].bind(target); } });
const { map }= toFunctional(Array);
const { charCodeAt }= toFunctional(String);
const { log }= toFunctional(console);
log(map(["A"], a=> charCodeAt(a, 0)));
Převádění na funkce pomocí toFunctional
Důležité je mít na paměti, že takovéto použití má důsledky mimojiné v hlášení chyb – první argument takovýchto funkcí je this
, takže například při zavolání map(["A"])
dostaneme chybu „Uncaught TypeError: missing argument 0 when calling function Array.prototype.map”.
Dále některé takto vytvořené funkce nejsou „funkcionální” (Pure function) – například Array.prototype.splice().
Pro funkcionální přístup potřebujeme některé další nástroje, jako například „pipe” funkci (viz dále). Jako lépe předpřipravené ucelené řešení lze použít nějakou knihovnu jako emphori/stark: Minimal and incredibly lightweight functional programming for JavaScript.
1
2
3
4
5
6
7
8
9
10
11
12
/**
* @param {...function} functions
* @returns {(mixed: any)=> any}
* @example
* console.log(pipe(
* a=> a+1,
* a=> a*2
* )(0));//= 2
*/
const pipe= (...functions)=>
Array.prototype.reduce.bind(functions,
(acc, currFunction)=> currFunction(acc));
Příklad definice „pipe” funkce.