32

我记得总是当我想作为回调参数传递给某个函数时,除非我使用该方法绑定到它,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'

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

4

2 回答 2

13

控制台 API 的 Editor's Draft曾经说过:

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

这不再包含在当前版本的规范中。

我认为 Chrome 和 Node.js 将其更改为像规范中那样工作,但似乎它甚至在它之前也是这样工作的。

我仍然很好奇它是什么时候改变的,原因是什么。

于 2016-09-14T21:23:46.573 回答
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,并且 sinestr没有在 中定义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控制台对象只有一个实例一样。

于 2016-09-21T02:31:59.873 回答