如何改变Javascript函数名称出现在toString()?



Function.name属性是可配置的,可以覆盖,但如果我尝试

function foo() {}
Object.defineProperty(foo, 'name', {value: 'bar'})

foo.toString()仍然显示为"function foo() {}",但我期望它是"function bar() {}"

你不可能100%可靠地做到这一点。这是因为Function.prototype.toString的定义,它使用[[SourceText]]内部插槽,它被设置为从用于创建函数的源代码创建的函数。它不使用name属性。

你也可以尝试重写函数上的toString,但是如果有人显式地在它上使用Function.prototype.toString,当然这仍然会失败。

如果你只是想用toString这样的东西作弊,也许你可以考虑使用Proxy

的例子:

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);

对于本机函数也是有效的。

注意:在2022年之前,浏览器环境不提供任何支持Proxy的API。事实上,规范还明确指出不应该检测Proxy。所以我认为这个方法是可靠的。

  • 如果你计划部署在服务器端,如Node.js,或特权环境,如浏览器扩展,它将能够被检测到。
  • 如果目标函数是自定义函数,确保它没有configurable: falsewritable: false)

相关内容

  • 没有找到相关文章

最新更新