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'
.
Когда и почему это изменилось? Описывает ли спецификация что-нибудь об этом?
Ответы
Ответ 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
, поскольку есть только один экземпляр объекта консоли.