console.log()在控制台以外的对象上调用

时间:2016-09-14 21:23:47

标签: javascript this console.log function-binding

我记得,当我想将console.log作为回调参数传递给某个函数时,除非我使用bind()方法绑定console,否则它无法正常工作它

例如:

const callWithTest = callback => callback('test');
callWithTest(console.log); // That didn't use to work.
callWithTest(console.log.bind(console)); // That worked (and works) fine.

请参阅Uncaught TypeError: Illegal invocation in javascript

但是,最近我注意到console.log()即使在除了控制台之外的对象上调用时也能正常工作。例如:

console.log.call(null, 'test');

记录'test'

何时以及为何会改变?规范是否对此有所说明?

2 个答案:

答案 0 :(得分:13)

Editor's Draft of Console API曾经说过:

  

记录API应该都是可调用的函数,允许它们作为参数传递给错误处理回调,forEach方法等。

这不再包含在the current version of the specification中。

我认为Chrome和Node.js将其更改为在规范中工作,但似乎它在此之前就已经发挥作用了。

我还好奇它什么时候改变了,原因是什么。

答案 1 :(得分:0)

我不知道改变的时间,但我知道它为什么不起作用。

考虑以下代码

callWithTest = callback => callback('test');
var Demo = function () {this.str = 'demo';}
Demo.prototype.getStr = function () { return this.str;}
demo = new Demo ();
demo.getStr(); // returns 'demo'
callWithTest(demo.getStr); // returns undefined
window.str = 'window';
callWithTest(demo.getStr); // returns 'window'

如果您跟踪代码,您将看到当通过另一个函数调用demo.getStr时,this引用window,并且str未定义window },它返回undefined。如果您直接调用它或使用demo绑定,this会引用demo,因此它会返回' demo'。

在nodeJS(v6.6.0)中,控制台模块中存在一个名为Console的类,用户可以将日志显式地传输到文件(或用户喜欢的任何流)。根据Node.js v6.6.0 api规范,

console = new Console(process.stdout, process.stderr);
浏览器中不存在

Console,因为它不是必需的。控制台的输出仅存在于用于调试的画布中,并且只有一个实例。用户不能,也不应该将控制台的输出管道传输到任何其他地方,因为它将成为一个严重的安全问题。因此,开发人员可以在日志函数中执行某些操作,例如var x = this.x || console.x,因为控制台对象只有一个实例。