2015-02-20 2 views
0

Трудно объяснить мой вопрос, поэтому я отправляю код.JavaScript-доступ к переменным, объявленным в функции вызова

function caller(func) { 
    function printMessage(message) { 
     console.log(message); 
    } 

    func(); 
} 

function callee() { 
    printMessage('hello world'); 
} 

caller(callee); 

Я хочу получить доступ к printMessage с вызываемым, но, как это в настоящее время стоит, это бросает ReferenceError. Я хотел бы избежать объявления printMessage глобально, если это возможно.

+0

Что вы пытаетесь достичь этим? Объект вроде 'console', который завершает реализацию? –

+0

Функция вызывающего абонента будет частью библиотеки, при этом функция вызываемого абонента будет записана пользователем. printMessage является частью API, поэтому пользователи должны иметь возможность вызвать его в своем коде. – AmorphousCrystal

ответ

0

eval, кажется, достигает этого довольно элегантно.

function caller(func) { 
    function printMessage(message) { 
     console.log(message); 
    } 

    eval('(' + func.toString() + ')();'); 
} 

function callee() { 
    printMessage('hello world'); 
} 

caller(callee); 
1

Вы можете передать функцию, которую вы хотите использовать внутри callee, в качестве параметра: callee; так долго, как вызывающий абонент имеет доступ, то callee не все равно, где он был определен:

function caller(func) { 
    .... 
    func(printMessage); 
} 

function callee(func) { 
    func("hello world"); 
} 
0

Одна вещь, которую вы могли бы сделать, чтобы иметь «вызывающему» вызова функции передается в нее, и распечатать возвращаемое значение ,

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); 

Редактировать

После прочтения ваших комментариев на вопрос, это может быть лучше подходит для ОО-подхода например:

//--- 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' 
+0

Это не разрешает доступ к printMessage из вызываемого абонента. – AmorphousCrystal

+0

Привет, я только что обновил код, чтобы иметь подход ООП, это позволяет библиотеке пользователей использовать и расширять функцию исходной библиотеки. (Хорошее чтение: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript) –

0

В принципе, вы не можете. Вложенный printMessage ограничен только областью caller.

Вы можете получить доступ к функции caller конструктора его calee.caller прототип, но он "заточен" под сферу вызывающей только ..

Просто для информации:

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/

Также , обратите внимание, что arguments.callee не будет поддерживаться и должен not be used

Предупреждение: 5-е издание ECMAScript (ES5) запрещает использование arguments.callee() в строгом режиме. Избегайте использования arguments.callee() в , либо предоставляя функциональные выражения имени, либо используя функцию , в которой функция должна вызывать себя.

Смежные вопросы