【问题标题】:arbitrary method names in javascript objectjavascript对象中的任意方法名称
【发布时间】:2012-03-31 10:18:10
【问题描述】:

我正在通过滚动我自己的带有一些我想要的额外功能的 console.log 变体来了解有关 javascript OOP 的更多信息。

到现在为止

debug = {
        consoleAvailable :  (typeof console == "object"),
        reportToConsole : 0,
        list            : [],
        setReporting    : function(level){
                            this.reportToConsole = level;
                            return true;
                        },
        log             : function(){
                            if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function")  console.log.apply(console, this.log.arguments);
                            this.list.push({'type':'log', 'msg':this.log.arguments});
                            return true;
                        },
};

这一切都很好,但我不想列出所有的日志、错误、警告等功能。相反,我希望能够只键入 debug.[something] 和一个函数来解释 [something] 并以与 log 函数工作相同的方式执行它。

这甚至可能吗?如果是这样,我该怎么做?

以下是一些我希望能够做到的示例。

debug.setReporting(1); //yes, I want to print to console

debug.log('foo', 'bar', 'baz'); //arbitrary number of arguments (this is already working)
debug.error('qux'); //function I haven't named, but there is a console.error function
debug.arbitraryName([1, 2, 3]); //no function for console.arbitraryName (ideally it would just console.log the argument(s)

编辑

好的,看起来@Rob W 的方法是可行的方法,但是我在实施时遇到了麻烦。似乎我没有正确或类似地传递函数的名称。我这里有一个小提琴显示问题http://jsfiddle.net/xiphiaz/mxF4m/

结论

看起来有太多浏览器怪癖,无法在不编写浏览器特定代码的情况下获得真正通用的调试器,所以我只是列出了我最常用的日志功能(日志、警告和错误)。这确实让我可以选择进一步自定义每个函数的结果。

结果:

debug = {
    consoleAvailable :  (typeof console == "object"),
    reportToConsole : 0,
    list            : [],
    setReporting    : function(level){
                        this.reportToConsole = level;
                        return true;
                    },
    log             : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function")  console.log.apply(console, this.log.arguments);
                        this.list.push({type:'log', msg:this.log.arguments});
                        return true;
                    },
    warn            : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.warn=="function") console.warn.apply(console, this.warn.arguments);
                        this.list.push({type:'warn', msg:this.warn.arguments});
                        return true;
                    },
    error           : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.error=="function")    console.error.apply(console, this.error.arguments);
                        this.list.push({type:'error', msg:this.error.arguments});
                        return true;
                    }
};

debug.setReporting(1);

debug.log('foo', 'bar', 'baz');
debug.error('qux');
debug.warn({test:"warning"});
console.log(debug.list);

【问题讨论】:

  • 请注意,在 IE 中,console.log 等内容不是函数,因此没有用于传递可变数量参数的 apply 方法。您必须对不同长度的单独调用进行硬编码:a = arguments; if(a.length == 1){ console.log(a[0])} if(arguments.length == 2){ console.log(a[0], a[1]}
  • 但在尝试apply 之前,我正在检查它是否是一个函数。这还不够吗?
  • 你应该迭代console,而不是console.__proto__。见jsfiddle.net/mxF4m/1
  • @Pumbaa80 我认为这一定是浏览器特定的东西,因为我在 Safari 中测试过这个,我得到一个错误,但它在 Firefox 中有效......
  • 对了。 Firefox 的控制台对象有点特别。当您打开控制台面板时,它会被注入window,并且只是一个包含一些方法的普通对象。不确定 Safari 的控制台实现。

标签: javascript function object arguments


【解决方案1】:

您可以使用Object.getOwnProprtyNames 方法获取所有属性(包括不可枚举的属性)的数组。然后,枚举它,检查console[key]是否是一个函数。如果是,请使用该方法扩展您自己的对象。

Object.getOwnPropertyNames(console)

至于你的最后一个问题,有一个非标准的__noSuchMethod__ 方法可以拦截对未定义函数的调用。

我强烈建议使用我提出的第一个方法,因为console 方法不会神奇地变大。它还使调试更容易。

【讨论】:

  • 这样的问题是我希望函数执行不管属性函数是否存在(函数需要将参数添加到dialog.list数组中)。我只想知道 console.functions 是否存在,这样我就可以调用它而不会出错。
  • 对不起,我看错了。 __noSuchMethod__ 似乎是我所追求的,但它不是标准的,这真是令人遗憾。 Kinda 违背了制作跨浏览器记录器的目的:(
  • @ZakHenry 我理解你的意图。我的第一个解决方案是实现这一目标的最简洁的方法。它会检测每个现有的 console.* 方法,这些方法可以添加到您的命名空间中。没有通用的 getter 方法。
  • @ZakHenry: __noSuchMethod__ 是邪恶的。为什么不像debug( 'arbitraryName', 1, 2) 那样更清晰地以字符串的形式显式传递内容?
  • @missingno 是的,我不会使用__noSuchMethod__。我正在尝试使语法尽可能简单,但是该方法可以工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多