如何在JavaScript中引用函数体中当前正在执行的函数



我正在开发一个JavaScript代码插入工具。

给定一段代码,假设我需要修改它来完成以下任务:

任务:在调用每个函数时为其分配一个新属性,并从函数体中访问该属性。

而且我只能在原始代码中添加新的代码行。其他更改(如删除(是不允许的。

考虑以下示例

foo();
function foo() { // All functions are assumed to have names

}

我可以通过添加两行这样的代码来修改它(基本上我通过引用函数名直接分配和访问添加的属性(:

foo.prop = ...; // give foo a new property
foo();
function foo() {
console.log(foo.prop); // access the property
}

然而,如果在foo内部声明了另一个同名函数,则上述解决方案不起作用。考虑以下示例。

foo();
function foo() { // All functions are assumed to have names
function foo() {...}
}

修改后:

foo.prop = ... // give foo a new property
foo();
function foo() { 
console.log(foo.prop); // property does not exist!
function foo() {...}
}

由于函数提升,外部foo被内部foo覆盖,因此,我无法使用函数名访问添加的属性。

在严格模式下使用arguments.callee也可能失败。所以这不是我的选择。有什么有效的方法可以完成这项任务吗?或者这实际上是不可能做到的?

我不确定您是在搜索漏洞,还是这只是一个学习练习。在任何情况下,您都可以在Object.prototype上设置它,它将被foo(和所有其他对象…包括函数(继承。然后,当你完成属性时,你可以delete

Object.defineProperty(Object.prototype, 'prop', {
configurable: true,
enumerable: true,
writable: true,
value: 'bar',
});
// invoke
foo(); // "bar"
const obj = {};
console.log('obj', obj.prop); // "obj" "bar"
obj.prop = 'baz';
console.log('obj', obj.prop); // "obj" "baz"
// "undefine" the prop
delete Object.prototype['prop'];
console.log('obj', obj.prop); // "obj" "baz"
// invoke again
foo(); // undefined
function foo() { 
console.log(foo.prop);
function foo() {}
}

您可以在此处使用bind函数:

function foo() {
console.log("outer", this.prop);
function foo() {
console.log("inner", this.prop)
}
foo();
}
const binded = foo.bind({prop: 2});
binded();

这会将函数中的This对象设置为特定值。请注意,this对象在内部foo函数中是不同的!

最新更新