【问题标题】:How to get function name within dynamic object function in native javascript如何在本机javascript中的动态对象函数中获取函数名称
【发布时间】:2015-04-27 04:34:50
【问题描述】:

我正在创建一个 js 库,它直接处理来自集合对象的项目操作,如下所示。我想允许为每个项目添加动态用户定义的对象函数,并通过集合对象直接使用索引使这些函数可用(请参阅示例实现)。

var item = function (obj) {
    this.foo = function () {
        alert("foo" + this.name);
    }
    for (var i in obj) {
        this[i] = obj[i]; //dynamic fields (overridable)
    }
}
var collection = function (list) {
    var self=this;
    this.items = [];
    if (list && list.length > 0) {
        for (var i in list) {
            var t = new item(list[i]); // create new item            
            for (var j in t) {
                if (typeof (t[j]) === "function") {
                    this[j]=function(index,arg1,arg2,arg3){                        
                        self.items[index][j](arg1,arg2,arg3); //not working (unreliable)
                        console.log(j) //undefined
                        // problem is here j cannot be visible from function handler.
                        //I need to call dynamic j function within handler
                    }
                }
                this.items.push(t); //push each item into collection
            }
        }
    }
}
var obj=new collection([
    {
        id:1,name:"apple",
        bar:function(arg){
            alert(arg+" "+this.name);
        }
    }
    ]);
    obj.foo(0); //equivalent to obj.items[0].foo();
    obj.bar(0,"parameter"); //equivalent to obj.items[0].bar("parameter");

如上面代码 sn-p 中的 cmets 所述,我无法从集合函数中动态调用项目的函数。 我怎样才能达到这个目的。请帮帮我。

【问题讨论】:

  • FUNCTION.name 会得到函数名,是你想要的吗?
  • 谢谢,但分配给(动态)字段的函数是匿名的。我要检索的是字段名。
  • 我为您的代码创建了一个 jsfiddle,它无需任何更改即可工作。 jsfiddle.net/avivshaked/o6g9k8s6
  • @user1147987,我在 fiddle 上尝试了你的代码,它运行良好,我没有得到你的问题,你能看看“jsfiddle.net/w8npva2b”吗?
  • 是的,它适用于一件物品,但如果收藏中的物品不止一件,它就不起作用。

标签: javascript function oop


【解决方案1】:

您无法从处理程序范围内获取相关字段名称。您需要做的是创建具有字段名称的新函数对象,即函数名称=字段名称。为此,您必须在将项目的动态函数指定为集合对象时做一些小技巧。在处理程序范围内,您可以通过 arguments.callee
Change this sn-p

转换函数名称
var t = new item(list[i]); // create new item            
        for (var j in t) {
            if (typeof (t[j]) === "function") {
                this[j]=function(index,arg1,arg2,arg3){                        
                    self.items[index][j](arg1,arg2,arg3); //not working (unreliable)
                    console.log(j) //undefined
                    // problem is here j cannot be visible from function handler.
                    //I need to call dynamic j function within handler
                }
            }
            this.items.push(t); //push each item into collection
        }

到此:

this.items.push(new item(list[i]));    
        var t=this.items[this.items.length-1];
        for (var j in t) {
           if (typeof (t[j]) === "function") {
                this[j]=new Function( "return function " + j + "(idx,arg1,arg2,arg3){console.log(this.items[idx]);var fn = arguments.callee.toString().substr('function '.length);fn = fn.substr(0, fn.indexOf('(')); if(this.items[idx][fn])this.items[idx][fn](arg1,arg2,arg3);}")();                    
            }
          //  this.items.push(t); //push each item into collection
        }                    
                }

jsfiddle 示例:http://jsfiddle.net/kyawlay/7528t7z8/1/

【讨论】:

  • 非常感谢。太不可思议了。但是当我将新项目添加到集合时,它会调用第一个对象,错误是什么,如下var obj=new collection([ { id:1,name:"apple", bar:function(arg){ alert(arg+" "+this.name); } },{ id:2,name:"orange", bar:function(arg){ alert("bar1 "+arg+" "+this.name); } } ]); obj.foo(1); //equivalent to obj.items[0].foo(); obj.bar(1,"parameter"); //equivalent to obj.items[0].bar("parameter");
  • 这是因为您将重点放在将项目分配给收藏。我更新答案请尝试这种方法。 jsfiddle 示例:jsfiddle.net/kyawlay/7528t7z8/1
猜你喜欢
  • 2011-01-10
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2021-08-13
  • 1970-01-01
  • 2013-08-27
相关资源
最近更新 更多