Проверить, является ли имя строковой переменной функцией 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
Другие вопросы по тегам