【问题标题】:how to access function caller context?如何访问函数调用者上下文?
【发布时间】:2012-03-23 16:49:24
【问题描述】:

我正在尝试了解 javascript 范围,我想知道是否在以下示例中:

// B can access 'context'
var a = function (context) {
    b = function () {
        console.log(context);
    };

    b();
};

a('nicccce'); // works!

// C can't access 'context'
var d = function () {
    console.log(context);
};

var c = function (context) {
    d();
};

c('oh oh'); // breaks

有没有办法从“d”函数访问“上下文”?

编辑:

我知道我可以将参数传递给 d 函数,这显然是 sane 要做的事情,但我想知道是否有另一种方法,也许使用 this.callee 作为this.callee.arguments[0].

【问题讨论】:

  • 您的示例说明了lexical and dynamic scoping 之间的区别。后者在 javascript 中不存在。
  • @thg435 完全理解我的问题:)

标签: javascript node.js


【解决方案1】:

你可以

1) 将context 传递给d,就像对ca 所做的那样。或
2) 将context 放入d 的词法范围内。

选项 2 听起来很复杂,但事实并非如此。这正是您在b 的情况下所做的事情。 context 被“封闭”在 b 的执行范围内,因为该变量在 b 的调用者范围内可用(因为它是 a 的参数)。

【讨论】:

    【解决方案2】:

    不,这是不可能的,并且会导致非常难看/不可读的意大利面条代码。

    为什么不能将它作为参数传递给函数?另一个(但也是丑陋的)解决方案是在两个函数都可以访问它的范围内声明变量(即在父函数或全局函数中)

    【讨论】:

      【解决方案3】:

      在您的示例中,“context”是一个作用域为函数 c() 和 a() 的变量(两个不同作用域中具有相同名称的两个不同变量)。

      从您如何命名变量“上下文”来看,我认为.call 是您要查找的内容?

      值得一提的是,一旦你忘记了块作用域,javaScript 中的作用域实际上非常简单。 function { ... } 之间出现的任何内容都是一个范围。

      【讨论】:

        【解决方案4】:

        在您的情况下,如果您在 c 中将上下文作为参数传递,它将不会中断:

        // C can access 'context'
        var d = function () {
        console.log(arguments[0]);
        };
        
        var c = function (context) {
        d(context);
        };
        
        c('oh oh'); // doesn't break
        

        并且在 d 中你将能够使用 argv/args 来访问它(记不清了) 所以像 args[0] 或 argv[0]

        编辑:

        使用参数更改代码

        【讨论】:

          【解决方案5】:

          定义一个位于顶级作用域的变量:

          (function(){
          
              var global;
          
              var d = function () {
                  console.log(global);
              };
          
              var a = function (local) {
                  global = local;
                  b = function () {
                      console.log(global);
                  };
                  b();
              };
          
          }())
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-14
            • 1970-01-01
            • 1970-01-01
            • 2019-03-09
            • 2019-10-18
            • 1970-01-01
            相关资源
            最近更新 更多