I am using JavaScript and getting a problem with the statement
console.log.bind(console)
Please tell me what does this statement actually do. I have applied this several times but it did not do anything.
The console. log() is a function in JavaScript which is used to print any kind of variables defined before in it or to just print any message that needs to be displayed to the user. Syntax: console.
Steps to Open the Console Log in Google Chrome By default, the Inspect will open the "Elements" tab in the Developer Tools. Click on the "Console" tab which is to the right of "Elements". Now you can see the Console and any output that has been written to the Console log.
Node. js provides a console module which provides tons of very useful ways to interact with the command line. It is basically the same as the console object you find in the browser. The most basic and most used method is console. log() , which prints the string you pass to it to the console.
log method, and its friends console. warn and console. error , lets you dump objects in the console. The only difference between these functions is their “type” classification, which looks slightly different and can be filtered when viewing the console output.
In JavaScript, this
within a function call is determined by how the function is called (for normal functions, see * below). If it's called as part of an expression retrieving an object property (e.g., foo.bar()
calls bar()
as part of a property retrieval operation getting it from foo
), this
is set to the object that the property came from during the call to the function.
Suppose you wanted a shorter form of console.log
, like f
. You might do this:
var f = console.log; // <== Suspect!
...but if the log
function relies on this
referring to the console
object during the call, then calling f("Message here")
won't work, because this
won't refer to console
.
Function#bind
is for just that situation: It lets you create a new function that, when called, will call the original with this
set to the value you give. So
var f = console.log.bind(console); // Still suspect, for a different reason
...should, in theory, give you a function, f
, that you can call to log to the console.
Except: Host-provided functions like console.log
(and alert
and getElementById
) aren't required to be "real" JavaScript functions (although on modern browsers they tend to be, or at least very close), and aren't required to have all of their features, inculding bind
. So if you're getting an error on that line, it may be that the engine you're using that line on doesn't support bind
on the console.log
function.
So what are "host-provided functions"? Any function not explicitly defined in the specification as being part of JavaScript, the language. So again, on a browser that's browser-related functions like alert
or console.log
and such.
I can think of two reasons that line might be giving you trouble:
The above: You're using a JavaScript engine that doesn't make console.log
a real function.
You're using the line above on IE with the Dev Tools closed. On IE when the dev tools aren't open, the console
object isn't defined, and so that line will throw a ReferenceError
.
If the end goal is to get a function you can call, say f("Message here")
, for console.log
, here's how you can do that dealing with both #1 and #2 above:
function f(item) {
if (typeof console != "undefined" && console.log) {
console.log(item);
}
}
That only lets you give one item, whereas console.log
lets you give multiple items (console.log("this", "that", "and the other")
), but if console.log
may not be a real JavaScript function, then it may not have Function#apply
, which makes it very hard to wrap it.
Now, if you don't care about getting the same output you'd get from console.log("this", "that", "and the other")
so long as you can see what's there, simply use console.log(arguments);
(arguments
is the built-in identifier for all arguments passed into a function). But if you want to replicate the exact output, you end up doing something like this:
function f() {
var a = arguments;
if (typeof console != "undefined" && console.log) {
if (console.log.apply) {
// It has Function#apply, use it
console.log.apply(console, arguments);
} else {
// Ugh, no Function#apply
switch (a.length) {
case 0: console.log(); break;
case 1: console.log(a[0]); break;
case 2: console.log(a[0], a[1]); break;
case 3: console.log(a[0], a[1], a[2]); break;
case 4: console.log(a[0], a[1], a[2], a[3]); break;
case 5: console.log(a[0], a[1], a[2], a[3], a[4]); break;
default:
throw "f() only supports up to 5 arguments";
}
}
}
}
...and that's just ugly.
* ES5 added bound functions, which are functions that have their this
value attached to them via binding:
// Normal function
function foo() {
console.log(this.name);
}
// Create a bound function:
var f = foo.bind(someObject);
It doesn't matter how you call f
, it will call foo
with this
set to someObject
.
* ES2015 (aka ES6) added arrow functions. With arrow functions, this
is not set by how the function is called; instead, the function inherits this
from the context in which it was created:
// Whatever `this` is here...
var f = () => { // <== Creates an arrow function
// Is what `this` will be here
};
Arrow functions are really handy when you're doing something like Array#forEach
within an object method:
this.counter = 0;
this.someArray.forEach(entry => {
if (entry.has(/* some relevant something */)) {
++this.counter;
}
});
Quick update on this matter, it seems that you don't need to bind the console to itself anymore.
Chromium started rolling out some deep changes on the console
object, which is now already bound to itself. https://chromium.googlesource.com/chromium/src.git/+/807ec9550e8a31517966636e6a5b506474ab4ea9
It also seems that all the other browsers have followed this path (tested on recent version of Firefox and in Node).
I guess, if you need to be compatible with old browsers, you would still need to manually bind the console, but for debug purposes, you can now omit the .bind(console)
:)
T.J. Crowder's answer helped me explain and solve a problem I had with redirecting console.log
output, but his solution for the "no Function#apply" case seemed arbitrarily limiting for many use-cases.
I rewrote his code like this which is a little cleaner and more functional:
function f() {
var a = arguments;
if (typeof console != "undefined" && console.log) {
if (console.log.apply) {
// It has Function#apply, use it
console.log.apply(console, arguments);
} else {
// Ugh, no Function#apply
var output = '';
for (i=0;i<arguments.length;i++) {
output += arguments[i] + ' ';
}
console.log(output);
}
}
}
console.log
separates arguments with a space, so I replicated that here as well. The primary limitation for this is that it does not handle arguments that are objects. You can stringify those if needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With