Проверить, является ли имя строковой переменной функцией javascript объекта
Как проверить, является ли строковый параметр, переданный в функцию, слишком вызываемым / функциональным, но не напрямую window.
,
Я знаю, что открытую / напрямую вызываемую функцию можно проверить с помощью синтаксиса window['functionName']
Но как насчет функции-члена, объявленной внутри проверяемого объекта?
В приведенном ниже примере openFunction()
можно назвать, но как позвонить obj1.foo()
?
Предпочитаю не использовать
eval()
Пример кода:
var obj1 = {
foo: function() {
alert("I'm a function");
}
}
function openFunction() {
alert("I know i am easily callable");
}
function callSomeone(txtcallback) {
var fn = window[txtcallback];
if (typeof fn === 'function') {
fn();
}
console.log(typeof fn);
}
callSomeone('openFunction'); //function
callSomeone('obj1.foo'); //undefined
3 ответа
Возвращается undefined
потому что ваш код эквивалентен window["obj1.foo"]
что не правильно.
Правильный способ доступа к foo
функция window["obj1"]["foo"]
,
Таким образом, вы должны "перебрать" через строку obj1.foo
,
Здесь я добавил GetProp
Функция, которая выполняет этот цикл и является рекурсивной, поэтому уровень вложенности не является проблемой.
var obj1 = {
foo: function() {
alert("I'm a function");
}
}
function openFunction() {
alert("I know i am easily callable");
}
function callSomeone(txtcallback) {
var fn = GetProp(window, txtcallback.split("."));
if (typeof fn === 'function') {
fn();
}
console.log(typeof fn);
}
function GetProp(obj, props) {
if(props.length == 0) {
return obj;
} else if(obj[props[0]] != undefined) {
obj = obj[props[0]];
return GetProp(obj, props.slice(1));
}
}
callSomeone('openFunction'); //function
callSomeone('obj1.foo'); //undefined
Попробуй это
var obj1 = {
foo: function() {
alert("I'm a function");
}
}
function openFunction() {
alert("I know i am easily callable");
}
function callSomeone(txtcallback) {
str =txtcallback.split(".");
temp = window;
for(check in str){
temp = temp[str[check]];
if (typeof temp === 'function') {
temp();
break;
}else if(typeof temp === 'undefined'){
break;
}
}
console.log(typeof temp);
}
callSomeone('openFunction'); //function
callSomeone('obj1.foo'); //function
Если вы хотите искать членов внутри вложенных карт, вы должны использовать рекурсивный подход.
function callSomeone(txtcallback) {
var keyPath = txtcallback.split(".");
var fn = keyPath.reduce(function (member, key) {
return member[key];
}, window);
if (typeof fn === 'function') {
fn();
}
console.log(typeof fn);
}
недостатком этого примера является то, что функция выполняется в глобальной области видимости. Если вам нужно сохранить область объекта контейнера, вам также необходимо сохранить область.
var obj1 = {
foo: function() {
alert("I'm a function");
return this;
}
}
function openFunction() {
alert("I know i am easily callable");
return this;
}
function callSomeone(txtcallback) {
var keyPath = txtcallback.split(".");
var scope = null;
var context = null;
var fn = keyPath.reduce(function (member, key) {
scope = member;
return member[key];
}, window);
if (typeof fn === 'function') {
context = fn.call(scope);
}
console.log(typeof fn, context);
}
callSomeone('openFunction'); //function
callSomeone('obj1.foo'); //undefined