【问题标题】:variable in module pattern not assigned issue模块模式中的变量未分配问题
【发布时间】:2016-07-20 11:04:17
【问题描述】:

我是 javascript 和模块模式的新手。 所以我正在尝试编写以下小库

(function(window, $){
    'use strict';


    function myLibrary(){
        var myLib = {};
        var options= {};
        var map;

        //_options =  {'map':ol.map, 'geojson': testdata}
        myLib.init = function init(_options){
            options = _options;

            map = _options.map;
            console.log("Initializing  ...");
            console.log("map : "+ map);
            console.log("options : "+ options);
        }

        myLib.map = map;
        myLib.options = options;

        return myLib;
    }

    if(typeof (window.testLib) === 'undefined'){
        window.testLib = myLibrary();
    }

})(window, $);

我首先使用以下参数调用 init 函数:

testLib.init( {'map':ol.map, 'geojson': testdata})

当我尝试访问地图和选项时出现问题

 testLib.map   // return undefined instead of the map object
 testLib.options   // reutrn {}  instead of  {'map':ol.map, 'geojson': testdata}

我在 init 中进行了分配,但它似乎不起作用。在 init() 中为 map 和 options 所做的分配似乎是 init() 本地的

我怎样才能对我用 var 声明的映射和选项进行分配??

感谢帮助

编辑:正确的句子,应该是:“我首先使用以下参数调用初始化函数:”

【问题讨论】:

    标签: javascript design-patterns module


    【解决方案1】:

    这里的作业与你想的不一样。

    myLib.map = map;
    myLib.options = options;
    

    在第一次运行时init() 尚未发生,所以mapundefinedoptions{}。然后稍后init() 运行并更改您的内部变量,但这根本不会更新myLib.map 的值,因为它是单独的变量。

    这种模式不适用于属性,相反,您需要可以访问该范围的函数。例如:

    myLib.getMap = function() { return map; };
    

    testLib.getMap() 应该获取并返回该内部变量。在这种模式中,函数充当数据的看门人。


    或者,如果您的目标环境支持它,您可以使用属性 getter。

    var myLib = {
      get map() { return map };
    }
    

    然后这将按您的预期工作,因为它在后台执行一个功能。

    testLib.map; // trigger property getter function.
    

    但这并不是普遍支持的,旧的 javascript 引擎也不支持。

    【讨论】:

    • 第一次调用init函数是用调用中显示的参数,我不会用空参数调用。
    • 我多次阅读您的回复,才意识到使用 'var' 声明变量会在函数范围内创建一个私有变量。
    • 我不能使用属性获取器,因为我正在使用自调用和函数。 getter 仅用于对象字面量。
    【解决方案2】:

    这是一个working solution,您应该使用this 设置地图和选项,因此它将成为对象的一部分,而不仅仅是private members

    (function(window, $){
        'use strict';
    
    
        function myLibrary(){
            var myLib = {};
            var options= {};
            var map;
    
            //_options =  {'map':ol.map, 'geojson': testdata}
            myLib.init = function init(_options){
                this.options = _options;
    
                this.map = _options.map;
                console.log("Initializing  ...");
                console.log("map : "+ map);
                console.log("options : "+ options);
            }
    
            myLib.map = map;
            myLib.options = options;
    
            return myLib;
        }
    
        if(typeof (window.testLib) === 'undefined'){
            window.testLib = myLibrary();
        }
    
    
    })(window, $);
    

    【讨论】:

      【解决方案3】:

      设置testLib.map 的时间map 未定义,因此当您访问testLib.map 时会返回,对于选项,该值仍然是您分配的第一个值,即{}

      要解决您在 init 方法上的问题,请像这样直接操作 myLib 对象

      (function(window, $){
          'use strict';
      
          function myLibrary(){
              var myLib = {};
              var options= {};
              var map;
      
              //_options =  {'map':ol.map, 'geojson': testdata}
              myLib.init = function init(_options){
                  options = _options;
                  map = _options.map;
      
                  // ADD THESE TWO LINES
                  myLib.map = map;
                  myLib.options = options
              }
      
              return myLib;
          }
      
          if(typeof (window.testLib) === 'undefined'){
              window.testLib = myLibrary();
          }
      
      })(window, $);
      

      注意

      正如 Alex Wayne 指出的那样,如果本地地图和选项变量没有其他用途,您可以删除它们的本地引用以使您的代码更整洁

      (function(window, $){
          'use strict';
      
          function myLibrary(){
              var myLib = {};
      
              //_options =  {'map':ol.map, 'geojson': testdata}
              myLib.init = function init(_options){
                  myLib.map = _options.map;
                  myLib.options = _options
              }
      
              return myLib;
          }
      
          if(typeof (window.testLib) === 'undefined'){
              window.testLib = myLibrary();
          }
      
      })(window, $);
      

      【讨论】:

      • 但是没有必要让这些变量是内部的和私有的。
      • @AlexWayne 刚刚提出了一种只需进行最少更改的方法。 OP可以解释这些变量是否还有其他用途
      • 我需要 map 属性,因为我必须对其进行一些操作,对于选项也是如此,我需要访问选项中的数据
      • @AlexWayne 和 eltonkamami 确实我不需要变量 'map' 和 'options' 是私有的。我可以只使用“myLib.map”myLib.options。但是通过在匿名函数内部进行赋值,很难看出myLib有一些属性,需要一个人去挖掘代码。
      猜你喜欢
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 2022-01-05
      相关资源
      最近更新 更多