Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

javascript - 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context

I am trying to create a simple debugging function that simply shows the caller of a function, like this:

function xe() {
  console.log(xe.caller().name)
}

With this I would just be able to add xe() to a function and it will log the calls to the function– just a short, simple addition to help with debugging. Debugging sugar, so to speak.

Unfortunately I get the error from the subject-line:

TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.

I am using Babel/ES6, which injects "use strict" at the top of every module. This may be the cause, but searching has yielded limited information on why the error is raised, and I would like to understand it better.

If strict mode is the problem I would prefer not to disable strict mode for the entire project– just for the module/function.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is the cause. From MDN:

in strict mode it's no longer possible to "walk" the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, fun.caller is the function that most recently called fun, and fun.arguments are the arguments for that invocation of fun. Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If fun is in strict mode, both fun.caller and fun.arguments are non-deletable properties which throw when set or retrieved:

If you're doing ES6, you can't in the general case disable strict mode. It's implicit during certain conditions such as when in an ES6 module.

If you're just debugging, I'd suggest just using a break point in a debugger and checking the stack frame, but I'm sure you know that already.

If you're just outputting debugging information you could also, I suppose just read the stack of an Error object:

console.log(new Error().stack);

You can globaly disable (but I realize this isn't what you want) use strict with babel Using either:

require("6to5").transform("code", { blacklist: ["useStrict"] });

or

$ 6to5 --blacklist useStrict

If you must strip it out on a module level, I suspect you'll have to do it yourself. Basic string replace perhaps?

Additionally, as has been pointed out in ES5. It should be xe.caller.name and not xe.caller().name or you would re-invoke the function.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...