Reputation: 64
It's hard to explain my question, so I'm posting some code.
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
printMessage('hello world');
}
caller(callee);
I want to access printMessage from callee, but as it currently stands, this throws a ReferenceError. I'd like to avoid declaring printMessage globally, if possible.
Upvotes: 0
Views: 1486
Reputation: 64
eval seems to achieve this rather elegantly.
function caller(func) {
function printMessage(message) {
console.log(message);
}
eval('(' + func.toString() + ')();');
}
function callee() {
printMessage('hello world');
}
caller(callee);
Upvotes: 0
Reputation: 7498
Basically, you can't. The nested printMessage
is limited to caller
scope only.
You can access the caller
constructor function by its calee.caller
prototype but it's "locked" under caller's scope only..
Just for info:
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
//you can access the caller's constructor from prototype..
var callerFunc = arguments.callee.caller.prototype;
console.log(callerFunc);
//you can get the actual code
var code = arguments.callee.caller.toString();
console.log(code);
//but you can't invoke the nested function which is under
//caller scope only...will throw ReferenceError
printMessage('hello world');
}
caller(callee);
jsfiddle: http://jsfiddle.net/ufxnoaL1/
Also, note that arguments.callee
will not be supported and should not be used
Warning: The 5th edition of ECMAScript (ES5) forbids use of arguments.callee() in strict mode. Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
Upvotes: 0
Reputation: 155
One thing you could do would be to have 'caller' call the function passed into it, and print the returned value.
function caller(func) {
function printMessage(message) {
console.log(message);
}
printMessage(func());
}
function callee() {
return 'hello world';
}
function callee2() {
return 'hello world 2';
}
caller(callee);
caller(callee2);
Edit
After reading your comments on question, this may be better suited to an OO approach e.g:
//--- Base 'libary' caller ---//
var caller = function() {
}
//--- Add out printMessage function to our base libary ---//
caller.prototype.printMessage = function(message){
console.log(message);
}
//--- Users 'libary' callee ---//
var callee = function() {
caller.call(this);
//--- Our users libary has a printing function ---//
this.print = function ( message ) {
this.printMessage("callee > " + message);
}
}
callee.prototype = Object.create(caller.prototype); // Set callee's prototype to caller's prototype
callee.prototype.constructor = callee; // Set constructor back to callee
//--- Using the users libary ---//
var userLibary = new callee();
userLibary.print("hello world"); // 'callee > hello world'
//--- The original libary's print method is still accessible ---//
userLibary.printMessage("hello world"); // 'hello world'
Upvotes: 0
Reputation: 49920
You could pass the function you want to use inside of callee
as a parameter to callee
; so long as the caller has access, then callee
doesn't care where it was defined:
function caller(func) {
....
func(printMessage);
}
function callee( func ) {
func("hello world");
}
Upvotes: 1