如何在JavaScript Revealing Module模式中返回字符串值

时间:2013-02-11 00:48:33

标签: javascript string design-patterns module

我在我的某个应用程序中使用了Revealing Module模式,但是在对象上调用init方法后,我无法返回字符串变量的值。目标是设置stringVar的值并从我的UI中检索它。 arrayVar工作。

谢谢, 克里斯

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

<script type="text/javascript">
    var viewModel = null;
    $(document).ready(function () {
        viewModel = new ViewModel();
        viewModel.init();
        // writes "object1" to ul
        $("#log").append("<li>" + viewModel.arrayVar[0] + "</li>");
        // writes "" to ul
        $("#log").append("<li>" + viewModel.stringVar + "</li>");
    });

    ViewModel = (function () {
        var
            arrayVar = new Array(),
            stringVar = '',
            init = function () {
                // load data from external source
                arrayVar.push("object1");
                arrayVar.push("object2");
                stringVar = "string value 1";
            };
        return {
            arrayVar: arrayVar,
            stringVar: stringVar,
            init: init
        };
    });

</script>

2 个答案:

答案 0 :(得分:0)

“这个”有效。双关语:)

init = function () {
    // load data from external source
    this.arrayVar.push("object1");
    this.arrayVar.push("object2");
    this.stringVar = "string value 1";
};

答案 1 :(得分:0)

这里的问题是字符串是不可变的,所以当你在stringVar中重新分配init时,它实际上是用一个新字符串替换变量,使得从构造函数返回的对象指向原始字符串。

解决这个问题的最简单方法是使用getter函数代替直接访问。如果您想要类似属性的访问,有几个选项。有__defineGetter__,不推荐使用,然后是ECMA5的getter,兼容性有限:

// your constructor
function() {
  // ...

  var getStr = function() {
    return stringVar;
  };

  // saving the returned object to a variable, as a few of the options
  // involve operating on an object.
  var m = {
    // typical getter function
    getStr: getStr,

    // ecma5 pretty syntax getter property
    get str1() { return getStr() }
  };

  // __defineGetter__ variant
  m.__defineGetter__("str2", getStr);

  // ecma5 Object.defineProperty variant
  Object.defineProperty(m, "str3", {get: getStr, enumerable: true});

  return m;
}

// access them like:
viewModel.getStr();
viewModel.str1;
viewModel.str2;
viewModle.str3;