How to refer to the currently executing function inside a function body in JavaScript

I am developing a JavaScript code instrumentation tool.

Given a piece of code, suppose I need to modify it to finish the following task:

Task: Assigning a new property to each function when it is invoked and access the property from within the function body.

And I am only allowed to add new lines of code into the original code. Other changes like deletion are NOT allowed.

Considering the following example

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

I can modify it by adding two lines of code like this (basically I directly assign and access the added property by referring to the function name):

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

However, if there is another function with same name declared inside foo, the above solution does not work. Considering the following example.

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

After modification:

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

Because of function hoisting, the outer foo is overridden by the inner foo, therefore, I cannot access the added property using function name.

Using arguments.callee may also fail in strict mode. So it is not an option for me. Are there any valid methods that can finish this task? Or it is actually impossible to do?


I'm not sure if you're searching for a vulnerability or if this is simply a learning exercise. In any case, you can set it on Object.prototype, and it will be inherited by foo (and all other objects... which include functions). Then you can delete the property when you're done with it:

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() {}
}