llaman Depende de donde y cómo la función es (o no es) declararon.
Si se trata de un mundial y no declarado a través de let name = ...
o const name = ...
sintaxis (y que no es un constructor de la clase declarada con class
), se puede comprobar mediante la búsqueda de ella como una propiedad del objeto global. (Esas advertencias son todas cosas ES2015, más abajo.) Puede obtener una referencia al objeto global a través del this
en modo suelto en ámbito global; los navegadores también te dan un número global llamado window
. Así que asumiendo un navegador:
if (typeof window[func_name] === "function") {
// ....
}
Si pudiera no ser global, sino más bien es sólo en su alcance debido a que su código se cierra sobre ella, o si se ha creado usando uno de esos mecanismos ES2015 he mencionado, hay realmente no hay buena manera de comprobar que no sea eval
:
if (eval("typeof " + func_name) === "function") {
// ....
}
Usando eval
es un último recurso, y hay que única utilizarlo con entrada controlada estrictamente. Pero cuando tienes que hacerlo, y tienes una entrada estrictamente controlada, está bien.
Acerca de las advertencias ES2015:
El nuevo let
, const
y class
son bestias muy interesantes: Cuando se utiliza en el ámbito global, crean globales, pero No crear propiedades en el objeto global. A partir de ES2015, aunque todas las propiedades del objeto global son globales, no todas las propiedades globales del objeto global. Todo es parte de tratar de controlar el espacio de nombres global ampliamente contaminado y también aportar una mayor seguridad al modelo de enlace de JavaScript. (Ahora que tenemos módulos verdaderos.)
Así que (tenga en cuenta que esto sólo funcionará en los navegadores de última generación):
// Global scope, in a browser (because I used `window` and `document.body`) that
// implements this aspect of ES2015 (as I write this, Firefox's SpiderMonkey
// doesn't, Chrome's V8 does on the latest Chrome; expect SpiderMonkey and IE
// to catch up pretty quick (didn't test IE Edge, maybe it's already there)
// Strict mode isn't required for this behavior, but for the moment V8 only
// supports the block-scoped constructs in strict mode.
"use strict";
let tbody = setup();
// Old-fashioned var: Creates a property on the global object, so
// we get "function, function"
var f1 = function() { /*...*/ };
result("var declaration", typeof f1, typeof window["f1"]);
// Function declaration: Creates a property on the global object, so
// "function, function"
function f2() {}
result("function declaration", typeof f2, typeof window["f2"]);
// `let` declaration: Doesn't create property on global object, so
// "function, undefined"
let f3 = function() { /*...*/ };
result("let declaration", typeof f3, typeof window["f3"]);
// `const` declaration: Doesn't create property on global object, so
// "function, undefined"
const f4 = function() { /*...*/ };
result("const declaration", typeof f4, typeof window["f4"]);
// `class` declaration: Doesn't create property on global object, so
// "function, undefined"
class C1 {}
result("class declaration", typeof C1, typeof window["C1"]);
function setup() {
document.body.insertAdjacentHTML(
"beforeend",
"<table>" +
"<thead>" +
"<tr><th>test</th><th>global</th><th>prop</th></tr>" +
"</thead>" +
"<tbody></tbody>" +
"</table>"
);
return document.body.querySelector("tbody");
}
function result(label, direct, win) {
tbody.insertAdjacentHTML(
"beforeend",
"<tr><td>" + [label, direct, win].join("</td><td>") + "</td></tr>"
);
}
body {
font-family: sans-serif;
}
table {
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 4px 8px;
}
de salida en los navegadores de última generación:
+----------------------+------------+-----------+
| test | global | prop |
+----------------------+------------+-----------+
| var declaration | function | function |
| function declaration | function | function |
| let declaration | function | undefined |
| const declaration | function | undefined |
| class declaration | function | undefined |
+----------------------+------------+-----------+
Nota: Algunos los transpilers no hacen cumplir esto rigurosamente, así que si ves diferentes resultados en el código transpilado, no te sorprendas.
para pasar argumentos: ventana [FUNC_NAME] (myArg1, myArg2); – mpemburn