1

the problem is very simple to understand yet tricky to implement.

if i have a predefined function(not one that i make) console.log("hello"). I would like to modify console.log() so that when i run console.log() anywhere, i can run a function where i get the arguments make some changes, example "hello" becomes "user1: hello".

The only way i can think of is:

Function MyOwnConsoleLog(string){
   string = "test.. " + string;
   console.log(string);
};

console.log = myCustomConsoleLogFunction
console.log("hello") //almost works!

This almost works but as you see console.log inside MyOwnConsoleLog is no longer console.log() XD which means that it will recurse infinitely and fail

Is it possible to make this work, maybe with some console.log.bind()/.apply()/.xxx or something else?

btw I have tried saving the old console.log() to another variable, but it seems pretty impossible to make a copy of this function, have tried alot of deep copies and other methods here at stackoverflow, none of them managed to make a fully working console.log() independent copy.

1

3 Answers 3

3

You can assign original console.log to a variable then assign new function to it.

var console_log = console.log;

console.log =  function MyOwnConsoleLog(string){
   string = "test.. " + string;
   console_log(string);
};

console.log("hello") // works!

But in reality it is not that simple since you only care about first argument so this:

console.log('Hello', 'world');

would only print 'Hello'

Something like this would work better

console_log.apply(this, arguments);
1

Store the original console.log() function as a global variable in the app.

let originalConsoleLog;

Function MyOwnConsoleLog(string){
   if (!originalConsoleLog) { 
    originalConsoleLog = console.log;
   }
   string = "test.. " + string;
   originalConsole.log(string);
};

console.log = myCustomConsoleLogFunction
console.log("hello")

I wouldn't recommend this approach lightly, because replacing/modifying global objects like this is ripe for unexpected errors, but it should work.

I've played around with this approach to create a TypeScript annotation to create a @JsonIgnore tag, similar to what might be seen in some Java frameworks.

1

I think the approach you mentioned at the end (keep a reference to the original console.log for your new function) does actually work for me in the console.

See this code:

const logfunc = console.log;

function consoleLogHighjack(foo) {
  logfunc("before the actual log");
  logfunc(foo);
}

console.log = consoleLogHighjack;

console.log("hello"); // prints "before the actual log" then "hello"

Note that the actual console log is able to handle multiple arguments, so a correct signature that mimics console.log would be advisable (see use of .apply in Molda's answer )

2
  • ah, beat me too it. this is the best approach I think.
    – Lucas
    Commented Oct 30, 2020 at 12:25
  • @Lucas I'm missing a point from Molda's answer, though, see my edit
    – Pac0
    Commented Oct 30, 2020 at 12:26