我正在尝试将console.log()方法有条件地分配给变量,如下所示:

var dbglevel = 1;
var dbg = (dbglevel > 0) ? console.log : function(){};

dbg('message'); // throws TypeError



它曾经可以工作,但是在Firefox 30中有所改变。现在我不知道它是否应该可以工作。我有疑问的原因是,我对文档对象也见过同样的事情。比较这两个函数赋值的结果,第一个是函数包装器,第二个是对该方法的直接赋值:
function qs1(q) { return document.querySelector(q); }; // wrapper
qs1('head'); // works

var qs2 = document.querySelector;
qs2('head'); // throws TypeError



我在这里看到什么?为什么直接将方法分配给变量会破坏其与父对象的“接口(interface)”?

我想这样做的原因有两个:

1.)赋值语法较短,我不必担心声明参数,
2.)更重要的是,我希望我的dbg()调用向控制台报告正确的文件和行号。如果该函数是包装器,则控制台将始终在该包装器中显示console.log调用的行号。我不想模拟行号记录,因为调用console.log的常规方法直接为您提供了一个可单击的链接,以查看以调用它的行为中心的源代码。

我不是,而是,而是在寻找一种解决方法,其中涉及FireBug,预处理(LESS/SASS)或第三方脚本之类的插件。该解决方案只需要在普通的Firefox 30或更高版本上运行,我要解决的特定问题是如何在我要有条件记录的每一行上压缩以下代码:
if (typeof cfg.DEBUG != 'undefined' && cfg.DEBUG > 2) console.log(something);

...对此...
dbg(something);

... dbg()函数执行任何适当的条件评估,然后显示与我直接调用console.log相同的行号。

最佳答案

有一个简单的解决方法:

var dbglevel = 1;
var dbg = (dbglevel > 0) ? function(msg){console.log(msg);} : function(){};

dbg('message'); // prints message

顺便说一句,将本地函数分配给var也会在Chrome中引发TypeError
问题是绑定(bind):当您像使用别名一样对函数进行别名时,会在全局对象上调用它们,而您需要依次将它们绑定(bind)到consoledocument

因此,正确的别名方式是:
var dbg = console.log.bind(console);

或者
var qs2 = document.querySelector.bind(document);

假设您至少正在运行ES5。因此,如果需要向后兼容,则可能需要使用类似上述解决方法的方法(也许可以通过使用applyarguments对象对某些可变参数进行详细说明)。

如果您确定可以使用ES5功能,请使用:
var dbglevel = 1;
var dbg = (dbglevel > 0) ? console.log.bind(console) : function(){};

dbg('message'); // prints message

09-21 00:01