Reputation: 6049
This Meteor sever code has printFuncName
as a private method to a IIFE. When it is called from a public method, it gives the error:
TypeError: Cannot read property 'name' of null
Why is it doing this and How can it be fixed so that it prints the function name where is is called from? Thanks
funcObj = (function() {
const printFuncName = (str) => {
const info = str ? ' ' + str + ' ' : ' ';
console.log(arguments.callee.caller.name + info); //<---- Error line
};
return {
myPub: () => {
printFunctionName('info');
}
}
}());
Upvotes: 0
Views: 56
Reputation: 288670
Assuming you want to access the caller of printFuncName
, the problem is that it's an arrow function, and therefore has no arguments
binding. You are accessing the arguments
of the IIFE.
Anyways, you should never use arguments.callee
. It's not standard and you can just reference the function:
(function() {
const printFuncName = (str) => {
const info = str ? ' ' + str + ' ' : ' ';
console.log(printFuncName.caller.name + info); // "myPub info " (maybe)
};
return {
myPub() {
printFuncName('info');
}
}
}()).myPub();
Be aware caller
is also not standard. You should not use this. Do not rely on it. It will throw in strict mode. May not work in sloppy mode.
Upvotes: 0
Reputation: 77099
Warning: what follows is a hack. The kosher way of doing this is passing the name as an arugment to the function. It's better than the arguments.callee
approach, though, so use it if you must.
If you create an Error
object, you can inspect the stack
to get the chain of function names:
new Error().stack.split('\n')
[ 'Error',
' at repl:1:1',
' at sigintHandlersWrap (vm.js:22:35)',
' at sigintHandlersWrap (vm.js:96:12)',
' at ContextifyScript.Script.runInThisContext (vm.js:21:12)',
...]
Your caller's name will be in that list, along with file and line/col information. Note that many JS functions are not named, so this is limited.
Upvotes: 2