Strict and non-strict code can be mixed. But you can't use caller even if the call to it is not in strict code. Does anybody know any workaround?
I tried this:
(function strict(){
"use strict";
nonStrict();//ok
nonStrictCaller();//error :(
})();
function nonStrict(){
return 011;//Octal literals are not allowed in strict mode
}
function nonStrictCaller(){
return nonStrictCaller.caller;
}
Strict and non-strict code can be mixed. But you can't use caller even if the call to it is not in strict code. Does anybody know any workaround?
I tried this:
(function strict(){
"use strict";
nonStrict();//ok
nonStrictCaller();//error :(
})();
function nonStrict(){
return 011;//Octal literals are not allowed in strict mode
}
function nonStrictCaller(){
return nonStrictCaller.caller;
}
Share
Improve this question
edited Mar 11, 2014 at 17:45
Kara
6,22616 gold badges53 silver badges58 bronze badges
asked Mar 19, 2012 at 21:02
QuadroidQuadroid
8252 gold badges9 silver badges15 bronze badges
6
-
1
You can pass
this
to the function, can't you? – gdoron Commented Mar 19, 2012 at 21:06 - i think you may wanna look here, especially in the ments stackoverflow./a/280396/575527 – Joseph Commented Mar 19, 2012 at 21:20
- The workaround is to make your code pliant with strict mode. That's sort of the point of strict mode; it's strict. In your case, it would mean making the caller accessible by some other means, like passing it by name as an argument. – user1106925 Commented Mar 19, 2012 at 21:31
- @amnotiam I'm writing framework, and I need caller to implement private & protected properties with access from methods in prototype. – Quadroid Commented Mar 19, 2012 at 23:34
- 2 If that's your approach, then your framework won't work in strict mode environments. Are you using the caller property to verify that some method was called from a prototyped method? Something similar? – user1106925 Commented Mar 20, 2012 at 0:48
1 Answer
Reset to default 12Here's an evil hack that only works in V8. The 140 bytes
version:
function x(a,b,c){function d(e,f){d=f}c=(b=Error)[a='prepareStackTrace'];b.captureStackTrace(b[a]=d,x);d.stack;b[a]=c;return d}
And the less cryptic version
if ('captureStackTrace' in Error) {
void function(){
function prepare(e, callsites){
return callsites;
}
function stack(f){
var e = {};
var oldPrepare = Error.prepareStackTrace;
Error.prepareStackTrace = prepare;
Error.captureStackTrace(e, f || stack.caller);
e = e.stack;
Error.prepareStackTrace = oldPrepare;
return e;
}
function lastReceiver(){
return stack(lastReceiver)[2].receiver;
}
var CallSite = stack()[0].constructor;
var callsiteMethods = {};
Object.getOwnPropertyNames(CallSite.prototype).forEach(function(key){
if (/^is|^get/.test(key)) {
callsiteMethods[key.replace(/^is|^get/, '')] = CallSite.prototype[key];
}
callsiteMethods.location = CallSite.prototype.toString;
});
CallSite.prototype.resolve = function resolve(){
for (var k in callsiteMethods)
this[k] = callsiteMethods[k].call(this);
}
}();
}