Reflexe funkcí

AndreaAndrea

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.