Can you get the property name through which a function was called?

bgoldst

I've done a lot of searching and some playing around, and I'm pretty sure the answer to this question is no, but I'm hoping a JavaScript expert might have a trick up his sleeve that can do this.

A JavaScript function can be referenced by multiple properties, even on completely different objects, so there's no such thing as the object or property that holds the function. But any time you actually call a function, you must have done so via a single object (at the very least, the window object for global function calls) and property on that object.

(A function can also be called via a function-local variable, but we can consider the function-local variable to be a property of the activation object of the scope, so that case is not an exception to this rule.)

My question is, is there a way to get that property name that was used to call the function, from inside the function body? I don't want to pass in the property name as an argument, or closure around a variable in an enclosing scope, or store the name as a separate property on the object that holds the function reference and have the function access that name property on the this object.

Here's an example of what I want to do:

var callName1 = function() { var callName = /* some magic */; alert(callName); };
var obj1 = {'callName2':callName1, 'callName3':callName1 };
var obj2 = {'callName4':callName1, 'callName5':callName1 };

callName1(); // should alert 'callName1'
obj1.callName2(); // should alert 'callName2'
obj1.callName3(); // should alert 'callName3'
obj2.callName4(); // should alert 'callName4'
obj2.callName5(); // should alert 'callName5'

From my searching, it looks like the closest you can get to the above is arguments.callee.name, but that won't work, because that only returns the name that was fixed to the function object when it was defined, and only if it was defined as a named function (which the function in my example is not).

I also considered that maybe you could iterate over all properties of the this object and test for equality with arguments.callee to find the property whose value is a reference to the function itself, but that won't work either (in the general case), because there could be multiple references to the function in the object's own (or inherited) property set, as in my example. (Also, that seems like it would be kind of an inefficient solution.)

Can this be done?

Sheepy

Short answer:

  1. No, you cannot get "the property name" used to call your function.
  2. There may be no name at all, or multiple names across different scopes, so "the property name" is pretty ill defined.
  3. arguments.callee is deprecated and should not be used.
  4. There exists no solution that does not use arguments or closure.

Long answer:

As thefourtheye commented, you should rethink what you are trying to do and ask that instead in a new question. But there are some common misconceptions, so I will try to explain why you cannot get the "simple property name".

The reason is because it is not simple.

Before we go ahead, let us clarify something. Activation Objects are not objects at all. The ECMAScript 5.1 specification calls them Environment Records (10.2.1), but a more common term is Scope chain. In a browser the global scope is (often) the window object, but all other scopes are not objects. There may be an object that you use to call a function, and when you call a function you must be in some scope.

With few exceptions, scopes are not objects, and objects are not scopes.

Then, there are many names.

  • When you call a function, you need to reference it, such as through an object property. This reference may have a name.
  • Scope chain has declarations, which always have a name.
  • A Function (the real function, not reference) may also have a function name - your arguments.callee.name - which is fixed at declaration.

Not only are they different names, they are not (always) the "the property name" you are seeking.

var obj = { prop : function f(){} }, func = obj.prop;
// "obj" and "func" are declarations.
// Function name is "f" - use this name instead of arguments.callee
// Property name is "prop"
func();     // Reference name is "func"
obj.prop(); // Reference names are "obj" and "prop"
// But they are the same function!
// P.S. "this" in f is undefined (strict mode) or window (non-strict)

So, a function reference may comes from a binding (e.g. function declaration), an Object (arguments.callee), or a variable. They are all References (8.7). And reference does have a name (so to speak).

The catch is, a function reference does not always come from an object or the scope chain, and its name is not always defined. For example a common closure technique:

(function(i){ /* what is my name? */ })(i)

Even if the reference does have a name, a function call (11.2.3) does not pass the reference or its name to the function in any way. Which keeps the JavaScript engine sane. Consider this example:

eval("(new Function('return function a(){}'))()")() // Calls function 'a'.

The final function call refers the eval function, which refers the result of a new global scope (in strict mode, anyway), which refers a function call statement, which refers a group, which refers an anonymous Function object, and which contains code that expresses and returns a function called 'a'.

If you want to get the "property name" from within a, which one should it get? "eval"? "Function"? "anonymous"? "a"? All of them? Before you answer, consider complications such as function access across iframes, which has different globals as well as cross origin restriction, or interaction with native functions (Function.prototype.bind for example), and you will see how it quickly becomes hell.

This is also why arguments.caller, __caller__, and other similar techniques are now all deprecated. The "property name" of a function is even more ill defined than the caller, almost unrealistic. At least caller is always an execution context (not necessary a function).

So, not knowing what your real problem is, the best bet of getting the "property name" is using closure.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Can you get the property name through which a function was called?

From Dev

Python: Get name of function which called this function

From Dev

Python: Get name of function which called this function

From Dev

If a Javascript object has a property which holds a reference to a function, can I get that property name from within the function itself?

From Dev

how to get or reflect the name of the bash function which is called?

From Dev

how to get a property name which represent a function in JS

From Dev

How can I get a function name when it is being called?

From Dev

How to get id of element which called function

From Dev

How to create view with the name which can be pass through function as a parameter in postgresql?

From Dev

javascript - Get name of function through a function

From Dev

Establishing a unit converter which can be called globally through terminal

From Dev

How do you get the name of a property using the property itself

From Dev

How do you get the name of a property using the property itself

From Dev

How to access the current element property name of the called function

From Dev

Get name of property from its own function

From Dev

can you get the pc user name in vbs?

From Dev

How can I get the name of a Kotlin property?

From Dev

Which line called the function?

From Dev

Why does function not get executed when called through web server?

From Dev

Python debugging: get filename and line number from which a function is called?

From Dev

Does the PHP function get called every time you use a variable?

From Dev

Get property name from a lambda which takes a dynamic parameter as input

From Dev

Can you evaluate a property name within a JS object?

From Dev

Can you change the value of the Name property of a Type at runtime?

From Dev

Can you return a property of a POCO object from Linq by determining name of it?

From Dev

Is there a method so you'd find out which/name of functions that were being called?

From Dev

Struct function which can get Any type

From Dev

Why does debuggers give you "undefined is not a function" instead of just telling you the name of the property/variable that is not a function?

From Dev

Can you call a function using the value of a variable as the function name?

Related Related

  1. 1

    Can you get the property name through which a function was called?

  2. 2

    Python: Get name of function which called this function

  3. 3

    Python: Get name of function which called this function

  4. 4

    If a Javascript object has a property which holds a reference to a function, can I get that property name from within the function itself?

  5. 5

    how to get or reflect the name of the bash function which is called?

  6. 6

    how to get a property name which represent a function in JS

  7. 7

    How can I get a function name when it is being called?

  8. 8

    How to get id of element which called function

  9. 9

    How to create view with the name which can be pass through function as a parameter in postgresql?

  10. 10

    javascript - Get name of function through a function

  11. 11

    Establishing a unit converter which can be called globally through terminal

  12. 12

    How do you get the name of a property using the property itself

  13. 13

    How do you get the name of a property using the property itself

  14. 14

    How to access the current element property name of the called function

  15. 15

    Get name of property from its own function

  16. 16

    can you get the pc user name in vbs?

  17. 17

    How can I get the name of a Kotlin property?

  18. 18

    Which line called the function?

  19. 19

    Why does function not get executed when called through web server?

  20. 20

    Python debugging: get filename and line number from which a function is called?

  21. 21

    Does the PHP function get called every time you use a variable?

  22. 22

    Get property name from a lambda which takes a dynamic parameter as input

  23. 23

    Can you evaluate a property name within a JS object?

  24. 24

    Can you change the value of the Name property of a Type at runtime?

  25. 25

    Can you return a property of a POCO object from Linq by determining name of it?

  26. 26

    Is there a method so you'd find out which/name of functions that were being called?

  27. 27

    Struct function which can get Any type

  28. 28

    Why does debuggers give you "undefined is not a function" instead of just telling you the name of the property/variable that is not a function?

  29. 29

    Can you call a function using the value of a variable as the function name?

HotTag

Archive