0

How to check if the string parameter passed in a function is too callable/function but not directly under window..

I know the open/ directly callable function can be checked using the syntax window['functionName']

But how about the member function declared inside an object to be checked?

In below example openFunction() can be called but how to call obj1.foo()?

Prefer not to use eval()

Example Code:

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

4

3 回答 3

1

尝试这个

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
于 2016-06-17T08:32:28.187 回答
1

如果您想在嵌套映射中查找成员,则必须使用递归方法。

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
于 2016-06-17T08:34:04.017 回答
1

它返回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

于 2016-06-17T08:34:23.070 回答