Function.name
property is configurable and can be overriden, but if I try
function foo() {}
Object.defineProperty(foo, 'name', {value: 'bar'})
foo.toString()
still shows up as "function foo() {}"
but I expected it to be "function bar() {}"
.
Function.name
property is configurable and can be overriden, but if I try
function foo() {}
Object.defineProperty(foo, 'name', {value: 'bar'})
foo.toString()
still shows up as "function foo() {}"
but I expected it to be "function bar() {}"
.
You can't do this 100% reliably. That's because of the definition of Function.prototype.toString
, which uses the [[SourceText]] internal slot, which is set as the function is being created from the source code that was used to create the function. It doesn't use the name
property.
You could try to override toString
on the function as well, but of course that would still fail if someone explicitly used Function.prototype.toString
on it.
If you just want to cheat with something like toString
, maybe you can consider using Proxy
.
Example:
const YouWannaChangeName = "modified";
function x(a, b, c) {
return 0;
}
console.log(x.toString());
x = new Proxy(x, {
get(target, prop, receiver) {
if ([Symbol.toPrimitive, "toString"].includes(prop)) {
return function () {
const re = new RegExp(`^function ${target.name}`);
return target.toString().replace(re, `function ${YouWannaChangeName}`);
};
} else {
return target[prop];
}
}
});
console.log(x.toString());
console.log("" + x);
This is also valid for native functions.
Note: Until 2022, the browser environment doesn't provide any Proxy
aware API. In fact, the spec also explicitly states that Proxy
shouldn't be detected. So I think this method is reliable.
configurable: false
and writable: false
)