模块模式中的变量未分配问题

时间:2016-07-19 20:05:54

标签: javascript design-patterns module

我是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?

声明赋值的地图和选项

感谢您的帮助

编辑:正确的句子,应该是:"我首先使用以下参数调用init函数:"

3 个答案:

答案 0 :(得分:0)

此处的作业并不符合您的想法。

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引擎没有支持。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

以下是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, $);