【问题标题】:Is this scoping possible in javascript?这个范围在javascript中可能吗?
【发布时间】:2011-01-11 07:14:32
【问题描述】:

我正在开发一个 javascript 框架。我有几个看起来像这样的独立脚本:

core.modules.example_module = function(sandbox){
    console.log('wot from constructor ==', wot);

  return{
    init : function(){
      console.log('wot from init ==', wot);
    }
  };
};

这个函数是从另一个外部脚本调用的。我正在尝试将变量传递给此函数,以便可以访问它们 without using the this keyword.

上面的例子会报错说 wot 是未定义的。

如果我将函数包装在一个匿名函数中并在那里声明变量,我会得到预期的期望结果

(function(){

var wot = 'omg';

core.modules.example_module = function(sandbox){
    console.log('wot from creator ==', wot);

  return{
    init : function(){
      console.log('wot from init ==', wot);
    }
  };
};

})();

我想要做的是在作用域链上进一步声明变量,以便可以在模块中访问它们,而无需像第二个示例那样使用 this 关键字。我不相信这是可能的,因为看起来函数执行范围在函数声明时是密封的。

update
为了澄清我试图定义 wot 的位置。在一个单独的 javascript 文件中,我有一个像这样调用注册模块函数的对象

core = function(){
   var module_data = Array();
   return{
    registerModule(){
      var wot = "this is the wot value";
      module_data['example_module'] = core.modules.example_module();
    }
  };
};

【问题讨论】:

  • 第一个例子中wot在哪里定义?
  • @musicfreak:OP 说他收到了 wot 未定义的错误。如果您没有在任何地方使用var 关键字定义变量,JS 会将其作为window 对象的属性来查找。
  • @Tobias:我明白这一点。我想知道 OP 想要访问的对象在哪里——换句话说,他在寻找什么范围。

标签: javascript scope javascript-framework lexical-closures


【解决方案1】:

您要查找的内容称为“dynamic scoping”,其中的绑定是通过搜索当前调用链来解决的。它在 Lisp 家族之外并不常见(Perl 支持它,通过 local 关键字)。 JS 不支持动态作用域,它使用lexical scoping

【讨论】:

    【解决方案2】:

    考虑这个例子,使用你的代码

    var core = {}; // define an object literal
    core.modules = {}; // define modules property as an object
    
    var wot= 'Muhahaha!';
    
    core.modules.example_module = function(sandbox){
    
      console.log('wot from creator ==', wot);
    
      return {
        init: function() {
           console.log('wot from init ==', wot);
    
        }
      }
    }
    
    // logs wot from creator == Muhahaha! to the console    
    var anObject = core.modules.example_module(); 
    
    // logs wot from init == Muhahaha! to the console
    anObject.init(); 
    

    只要wotcore.modules.example_module 执行点的作用域链中的某个位置定义,它就会按预期工作。

    有点跑题了,但您已经谈到了函数的范围。函数具有词法作用域,即它们在定义(而不是执行)时创建作用域,并允许创建闭包;当一个函数保持到它的父作用域的链接时,即使在父作用域返回后,也会创建一个闭包。

    【讨论】:

      【解决方案3】:

      var wot; 放在构造函数的开头应该这样做

      core.modules.example_module = function(sandbox){
        var wot;
        wot = 'foo'; //just so you can see it working
        console.log('wot from constructor ==', wot);
      
        return{
          init : function(){
            console.log('wot from init ==', wot);
          }
        };
      };
      

      【讨论】:

        猜你喜欢
        • 2015-08-17
        • 1970-01-01
        • 2011-06-08
        • 2020-04-18
        • 1970-01-01
        • 1970-01-01
        • 2022-08-11
        • 1970-01-01
        • 2018-12-26
        相关资源
        最近更新 更多