【问题标题】:check if string variable name is a javascript fuction of an object检查字符串变量名称是否是对象的 javascript 函数
【发布时间】:2016-10-18 23:45:54
【问题描述】:

如何检查函数中传递的字符串参数是否太可调用/函数但不是直接在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

【问题讨论】:

标签: javascript function callback javascript-objects callable-object


【解决方案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

【讨论】:

  • 通常我会使用 lodash 之类的库来完成此操作。这只是展示了它是如何工作的。在 lodash 中,我可能会使用 _.resultlodash.com/docs#result
【解决方案2】:

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

【讨论】:

  • 谢谢,我发现你的编码解决方案是最专业的方式。
  • 我对此提出了扩展问题。如果我想维护对象的索引(id)变量/成员。如此称呼它失去了它的价值。 var obj1 = { id: 0, foo: function() { ++this.id; alert("id = " + this.id); } }
  • 在这种情况下,请尝试 JsonPath。它应该可以满足您的需要。
  • this.obj1.idwindow.obj1.id 替换this.id 有效。 (如果你能解释一下有什么区别。)但是为什么不根据 JsonPath 教程的语法工作 $.obj.id 工作?
【解决方案3】:

试试这个

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

【讨论】:

    猜你喜欢
    • 2011-05-02
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多