Aggiunta di console.log a ogni funzione automaticamente

C’è un modo per far sì che qualsiasi funzione emetta un’istruzione console.log quando viene chiamata registrando un hook globale da qualche parte (cioè senza modificare la funzione stessa) o tramite altri mezzi?

Ecco un modo per aumentare tutte le funzioni nel namespace globale con la funzione di tua scelta:

function augment(withFn) { var name, fn; for (name in window) { fn = window[name]; if (typeof fn === 'function') { window[name] = (function(name, fn) { var args = arguments; return function() { withFn.apply(this, args); return fn.apply(this, arguments); } })(name, fn); } } } augment(function(name, fn) { console.log("calling " + name); }); 

Un lato negativo è che nessuna funzione creata dopo aver chiamato l’aumento avrà il comportamento aggiuntivo.

Se si desidera una registrazione più mirata, il seguente codice registrerà le chiamate di funzione per un particolare object. È anche ansible modificare i prototipi Object in modo che anche tutte le nuove istanze vengano registrate. Ho usato Object.getOwnPropertyNames invece di … in, quindi funziona con le classi ECMAScript 6, che non hanno metodi enumerabili.

 function inject(obj, beforeFn) { for (let propName of Object.getOwnPropertyNames(obj)) { let prop = obj[propName]; if (Object.prototype.toString.call(prop) === '[object Function]') { obj[propName] = (function(fnName) { return function() { beforeFn.call(this, fnName, arguments); return prop.apply(this, arguments); } })(propName); } } } function logFnCall(name, args) { let s = name + '('; for (let i = 0; i < args.length; i++) { if (i > 0) s += ', '; s += String(args[i]); } s += ')'; console.log(s); } inject(Foo.prototype, logFnCall); 

Ecco alcuni Javascript che sostituisce aggiunge console.log ad ogni funzione in Javascript; Gioca con esso su Regex101 :

 $re = "/function (.+)\\(.*\\)\\s*\\{/m"; $str = "function example(){}"; $subst = "$& console.log(\"$1()\");"; $result = preg_replace($re, $subst, $str); 

È un ‘trucco veloce e sporco’ ma lo trovo utile per il debug. Se hai molte funzioni, fai attenzione perché questo aggiungerà molto codice. Inoltre, RegEx è semplice e potrebbe non funzionare per nomi / dichiarazioni di funzioni più complessi.

Metodo proxy per registrare chiamate di funzione

C’è un nuovo modo di utilizzare Proxy per ottenere questa funzionalità in JS. supponiamo di voler avere un console.log ogni volta che viene chiamata una funzione di una class specifica:

 class TestClass { a() { this.aa = 1; } b() { this.bb = 1; } } const foo = new TestClass() foo.a() // nothing get logged 

possiamo sostituire la nostra istanza di class con un Proxy che sovrascrive ogni proprietà di questa class. così:

 class TestClass { a() { this.aa = 1; } b() { this.bb = 1; } } const logger = className => { return new Proxy(new className(), { get: function(target, name, receiver) { if (!target.hasOwnProperty(name)) { if (typeof target[name] === "function") { console.log( "Calling Method : ", name, "|| on : ", target.constructor.name ); } return new Proxy(target[name], this); } return Reflect.get(target, name, receiver); } }); }; const instance = logger(TestClass) instance.a() // output: "Calling Method : a || on : TestClass" 

controlla che funzioni effettivamente in Codepen


Ricorda che l’utilizzo di Proxy ti offre molte più funzionalità rispetto al solo logging dei nomi di console.

Anche questo metodo funziona anche in Node.js.

In realtà è ansible albind la propria funzione a console.log per tutto ciò che carica.

 console.log = function(msg) { // Add whatever you want here alert(msg); }