Představte si, že potřebujete vypsat názvy parametrů funkce. Máte psát logiku, která se řídí tím jak vypadá rozhraní funkce.
Funkce jsou objekty, takže byste očekávali, že bude někde i metoda vracející seznam názvů parametrů. Bohužel, není tomu tak.
Jako řešení lze použít Function.prototype.toString()
na konverzi funkce na řetězec, který pak lze analyzovat, aby se zjistily názvy parametrů.
Příklad:
function argumentNames(fun) {
const names = fun.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function foo(bar, baz) {}
console.log(argumentNames(foo)); // Výstup: [ 'bar', 'baz' ]
Změna kontextu funkce
Funkci můžete změnit this
ve volání funkce pomocí konstrukce .call()
, .apply()
a .bind()
.
Zde je ukázka místo slibů. Pomocí call
voláme funkci a nastavit hodnotu "this" na konkrétní objekt, který si zvolíte.
const obj = {
name: 'Můj objekt'
};
function getName() {
return this.name;
}
console.log(getName.call(obj)); // Výstup: 'Můj objekt'
Tedy když jste nad objektem zavolali x
pomocí metod .call(x)
, .apply(x)
, pak this
se rovnalo x
.
Function.apply
volá funkci s daným kontextem (this) a argumenty v poli. Existuje v JS už velmi dlouho a je široce používaná.
Reflect.apply je relativně novější a byla přidána ve standardu ECMAScript 2015 (ES6) jako součást nového Reflect objektu, který se snaží poskytnout lepší API pro reflexivní operace.