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

时间:2021-03-10 16:55:18

I remember that always when I wanted to pass console.log as a callback parameter to some function, it didn't work unless I used the bind() method to bind console to it.

我记得,当我想将console.log作为回调参数传递给某个函数时,除非我使用bind()方法将控制台绑定到它,否则它不起作用。

For example:

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

See Uncaught TypeError: Illegal invocation in javascript.

请参阅Uncaught TypeError:javascript中的非法调用。

However, recently I noticed that console.log() works fine even when called on object other than console. For example:

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

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

logs 'test'.

When and why did it change? Does the specification say anything about it?

它何时以及为何会改变?规范是否说明了什么?

2 个解决方案

#1


13  

Editor's Draft of Console API used to say:

编辑器的Console API草案曾经说过:

Logging APIs SHOULD all be callable functions allowing them to be passed as arguments to error handling callbacks, forEach methods, etc.

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

This is no longer included in the current version of the specification.

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

I thought that Chrome and Node.js changed it to work like in the specification, but it seems that it worked like that even before it.

我认为Chrome和Node.js改变了它的工作方式,就像在规范中一样,但它似乎在它之前就像那样工作。

I'm still curious when did it change and what was the reason of that.

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

#2


0  

I don't know when the change was made, but I have an idea about why it didn't work.

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

Consider the following code

请考虑以下代码

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'

If you trace the code, you will see that when demo.getStr gets called through another function, this refers to window, and sine str is not defined within window, it returns undefined. If you called it directly or bind with demo, this refers to demo and thus it returns 'demo'.

如果你跟踪代码,你会看到当通过另一个函数调用demo.getStr时,这引用了window,而sine str没有在window中定义,它返回undefined。如果您直接调用它或使用demo绑定,则表示demo,因此它返回'demo'。

In nodeJS (v6.6.0), there exists a class called Console within the console module which user can explicitly pipe logs into a file (or whatever stream a user like). According to Node.js v6.6.0 api specification,

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

console = new Console(process.stdout, process.stderr);

Console does not exist in browser as it isn't necessary. The output of console only exists in a canvas used for debugging, and there are exactly one instance of it. User can't, and should not be able to, pipe output of console to any other places as it will become a serious security issue. Because of this, developers can do something within the log function like var x = this.x || console.x as there is exactly one instance of the console object.

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

#1


13  

Editor's Draft of Console API used to say:

编辑器的Console API草案曾经说过:

Logging APIs SHOULD all be callable functions allowing them to be passed as arguments to error handling callbacks, forEach methods, etc.

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

This is no longer included in the current version of the specification.

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

I thought that Chrome and Node.js changed it to work like in the specification, but it seems that it worked like that even before it.

我认为Chrome和Node.js改变了它的工作方式,就像在规范中一样,但它似乎在它之前就像那样工作。

I'm still curious when did it change and what was the reason of that.

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

#2


0  

I don't know when the change was made, but I have an idea about why it didn't work.

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

Consider the following code

请考虑以下代码

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'

If you trace the code, you will see that when demo.getStr gets called through another function, this refers to window, and sine str is not defined within window, it returns undefined. If you called it directly or bind with demo, this refers to demo and thus it returns 'demo'.

如果你跟踪代码,你会看到当通过另一个函数调用demo.getStr时,这引用了window,而sine str没有在window中定义,它返回undefined。如果您直接调用它或使用demo绑定,则表示demo,因此它返回'demo'。

In nodeJS (v6.6.0), there exists a class called Console within the console module which user can explicitly pipe logs into a file (or whatever stream a user like). According to Node.js v6.6.0 api specification,

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

console = new Console(process.stdout, process.stderr);

Console does not exist in browser as it isn't necessary. The output of console only exists in a canvas used for debugging, and there are exactly one instance of it. User can't, and should not be able to, pipe output of console to any other places as it will become a serious security issue. Because of this, developers can do something within the log function like var x = this.x || console.x as there is exactly one instance of the console object.

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