JavaScript访问在调用函数中声明的变量

时间:2015-02-20 15:57:02

标签: javascript scope

很难解释我的问题,所以我发布了一些代码。

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

    func();
}

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

caller(callee);

我想从被调用者访问printMessage,但是当前它会抛出一个ReferenceError。如果可能的话,我想避免全局声明printMessage。

4 个答案:

答案 0 :(得分:1)

您可以将callee内部要使用的功能作为参数传递给callee;只要调用者具有访问权限,callee就不关心它的定义:

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

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

答案 1 :(得分: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);

修改

在阅读了您对问题的评论后,这可能更适合OO方法,例如:

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

答案 2 :(得分: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()   要么给函数表达式命名,要么使用函数   函数必须调用自身的声明。

答案 3 :(得分:0)

eval似乎相当优雅。

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

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

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

caller(callee);