我正在尝试将 console.log() 方法的条件赋值实现为变量,如下所示:
var dbglevel = 1;
var dbg = (dbglevel > 0) ? console.log : function(){};
dbg('message'); // throws TypeError
TypeError:在未实现接口的对象上调用“log” 控制台。
它曾经可以工作,但在 Firefox 30 中发生了一些变化。现在我不知道它是否曾经“应该”工作。我怀疑的原因是我在 document 对象上看到了同样的事情。比较这两个函数赋值的结果,第一个是函数包装器,第二个是直接赋值给方法:
function qs1(q) { return document.querySelector(q); }; // wrapper
qs1('head'); // works
var qs2 = document.querySelector;
qs2('head'); // throws TypeError
TypeError:在未实现的对象上调用了“querySelector” 接口文档。
我在这里看到了什么?为什么直接将方法赋值给变量会破坏其与其父对象的“接口”?
我想这样做的原因有两个:
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
顺便说一下,在 Chrome 中将原生函数分配给
var
也会抛出
TypeError
。
问题在于绑定:当您像您一样为函数别名时,它们会在全局对象上调用,而您需要将它们依次绑定到 console
或 document
。所以别名的正确方法是:
var dbg = console.log.bind(console);
或
var qs2 = document.querySelector.bind(document);
假设您至少运行 ES5。因此,如果您需要向后兼容性,您可能需要使用类似于上面的解决方法的方法(也许使用
apply
和
arguments
对象来考虑可变数量的参数)。如果您确定可以访问 ES5 功能,请使用:
var dbglevel = 1;
var dbg = (dbglevel > 0) ? console.log.bind(console) : function(){};
dbg('message'); // prints message
var
的使用更改为
let
和 const
,在这种情况下我更喜欢)
let dbglevel = 1;
const dbg = (dbglevel > 0) ? console.log.bind(console) : function(){};
dbg('message'); // prints message
宣布
dbg
时,是
dbglevel === 1
;所以在那一刻,dbg
绑定到 console.log
,而 dbglevel
的值已关闭。由于 dbglevel
的关闭,“else”替代函数永远不会被调用,无论
dbglevel
未来发生任何变化。
dbg
函数将打印以控制台它作为参数接收到的所有后续消息。相反,如果我们定义dbg
这样的东西:
let dbglevel;
const dbg = (dbglevel > 0) ? console.log.bind(console) :
function(){console.log(`Sorry, debuglevel is ${dbglevel}`);};
...然后
dbg
将
always调用“else”函数并打印“抱歉”消息,包括
dbglevel
的 current 值,因为第一个替代方案有一个闭包 where dbglevel === undefined
。与前面的示例的重要区别在于,“else”函数不会关闭 dbglevel
的值,因此它实际上读取 dbglevel
的 current值:
dbglevel > 0
// --> false
dbg('I am a debug message');
// --> Sorry, debuglevel is undefined
dbglevel = 3 // dbglevel > 0
dbg('I am a debug message');
// --> Sorry, debuglevel is 3
[请注意:因为我在 stackoverflow 中还没有足够的权限,所以我无法撰写或回复评论。]