How to proxy Function.prototype?

I tried to proxy Function.prototype.

I created a new Proxy and rewrote the toString method, however console.log('cas') doesn’t work, why?

Function.prototype = new Proxy(Function.prototype, {
  get: function(target, property, receiver) {},
  set: function(target, property, value, receiver) {
    console.log('cas')
  }
})
Function.prototype._toString = Function.prototype.toString;
Function.prototype.toString = function() {
  console.log('bb')
  return this._toString()
}

>Solution :

I created a new Proxy and rewrote the toString method, however console.log('cas') doesn’t work, why?

The answer is simple: Function.prototype is not writable.

console.config({ maximize: true });
console.log(Object.getOwnPropertyDescriptor(Function, 'prototype'));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

As for why JS didn’t throw an error… It’s JS. What do you expect?

On the other hand, you can use 'use strict' to make these kinds of error explicit (thanks @Keith).

To prevent Function#toString() from being overwritten, you can re-define it:

Object.defineProperty(Function.prototype, 'toString', {
  value: Function.prototype.toString,
  writable: false,
  configurable: false
});

Try it:

console.config({ maximize: true });

function f() {}

console.log(f.toString()); // function f() {}

Object.defineProperty(Function.prototype, 'toString', {
  value: Function.prototype.toString,
  writable: false,
  configurable: false
});

Function.prototype._toString = Function.prototype.toString;
Function.prototype.toString = function() {
  console.log('overwritten');
  return Function.prototype._toString.call(this);
}

console.log(Object.hasOwn(Function.prototype, '_toString')); // true
console.log(Object.hasOwn(Function.prototype, 'toString')); // Also true
console.log(f.toString()); // function f() {}, not tainted.
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Leave a Reply