Подтвердить что ты не робот

Console.log() вызывает объект, отличный от консоли

Я помню, что всегда, когда я хотел передать 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: Незаконный вызов в javascript.

Однако недавно я заметил, что console.log() отлично работает даже при вызове на объект, отличный от консоли. Например:

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

logs 'test'.

Когда и почему это изменилось? Описывает ли спецификация что-нибудь об этом?

4b9b3361

Ответ 1

Редактор проекта API консоли:

API ведения журналов ДОЛЖНЫ все быть вызываемыми функциями, позволяющими передавать их в качестве аргументов для обратных вызовов обработки ошибок, для всех методов и т.д.

Это больше не включено в текущую версию спецификации.

Я думал, что Chrome и Node.js изменили его на работу, как в спецификации, но похоже, что он работал так же, как и раньше.

Мне все еще интересно, когда это изменилось и в чем причина.

Ответ 2

Я не знаю, когда было сделано изменение, но у меня есть представление о том, почему это не сработало.

Рассмотрим следующий код

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, а sine str не определяется внутри window, он возвращает undefined, Если вы вызвали его напрямую или связали с демо, this ссылается на демонстрацию и, следовательно, возвращает "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, поскольку есть только один экземпляр объекта консоли.