【问题标题】:Getting undefined from javascript module property从 javascript 模块属性中获取未定义
【发布时间】:2013-05-26 18:25:37
【问题描述】:

我感觉我遗漏了一些明显的东西。我正在从我的 javascript 模块返回一个变量,但它一直返回未定义。

这是模块:

var MyNs = MyNs || {}; 
MyNs.Global = function () {
   var privateTestVar;
   var init = function () {
       if (privateTestVar == null ) {
           privateTestVar = "this is a test" ;
           console.log( 'Init: ' + privateTestVar);
       }
   };

   var Public = {
       init: init,
       TestVar: privateTestVar
   }

   return Public;
} ();

来电:

MyNs.Global.init();console.log( 'Called: ' +MyNs.Global.TestVar);

init 函数中的 console.log 工作正常并返回值,但其他控制台日志返回 undefined。我完全想念它。任何帮助将不胜感激。

更新:我对代码做了一些改动,如下:

    var privateTestVar = function () { return 'Test!'; }

var Public = {
    TestVar: privateTestVar
}

以及它的变体,但它会将这个确切的文本返回到控制台:“function () { return 'Test!'; }”

【问题讨论】:

    标签: javascript


    【解决方案1】:

    Public 分配到这里的时候:

    var Public = {
        init: init,
        TestVar: privateTestVar
    }
    

    privateTestVar 仍然未定义(因为 init() 尚未运行)所以TestVar 属性被初始化为privateTestVar 的值,即undefined

    TestVar 属性被分配了privateTestVar 的值。如果它最初是未定义的(在本例中就是这样),它将保持这种状态,直到您为 TestVar 属性分配不同的东西。我不会自动继承 privateTestVar 的未来值,这可能是您所期望的。 Javascript 没有办法指定一个变量将始终包含分配给另一个变量的任何内容。 privateTestVar 和 TestVar` 属性都有自己的值。给一个变量赋值不会影响另一个变量。

    【讨论】:

    • 其实我是先调用init函数,它应该给privateTestVar赋值,让它适合返回。
    • @JoshC - init() 在哪里调用?在为TestVar 分配privateTestVar 的值之前,您的示例中没有调用它,这就是TestVar 包含undefined 的原因。 init() 必须在 TestVar 属性被创建和初始化之前被调用。
    • 这样调用:MyNs.Global.init();console.log('Called: ' +MyNs.Global.TestVar);
    • @JoshC - 请阅读我多次写过的内容。你打电话太晚了。当您调用init() 时,TestVar 的值已经在Public 的声明中设置。所以你调用init() 不会以任何方式影响TestVar 属性的值。
    • 好吧...我明白你的意思了...对不起...我读了几遍。我不想通过返回 public 来理解这一点,这意味着它首先被调用。
    【解决方案2】:

    我建议将私有变量设为真正的私有变量,改用 getter。这将正常工作:

    var Public = {
        init: init,
        getVar: function() { return privateTestVar; }
    }
    
    MyNs.Global.init();console.log( 'Called: ' +MyNs.Global.getVar());
    

    【讨论】:

    • 好吧....这真的很奇怪...现在它返回函数中的实际文本。控制台是这样写的:“调用:function () { return privateTestVar; }”
    • 这意味着您正在尝试记录函数本身,而不是其结果。不要忘记括号 (Global.getVar())。
    【解决方案3】:

    问题如@jfriend00 所述。把代码改成

    var init = function () {
        if (privateTestVar == null ) {
            privateTestVar = "this is a test" ;
            Public.TestVar = privateTestVar;
            console.log( 'Init: ' + privateTestVar);
        }
    };
    

    我没有对此进行测试,但理论上它应该可以工作。

    【讨论】:

    • 使用raina77ow 的建议。这样更好。
    【解决方案4】:

    我认为这是您正在寻找的结构:

    function PrivateFunc(private, public){
      this.privateVar = private;
      this.publicVar = public;
    }
    function PublicFun(public){
      this.publicVar = public;
      if(this.publicVar == null)this.publicVar = 'This is a public variable.';
      this.PrivateFun = function(private){
        return new PrivateFunc(private, this.publicVar);
      }
    }
    
    var pf = new PublicFun('public variable');
    var pv = pf.PrivateFun('private variable');
    console.log('pf.publicVar = '+pf.publicVar);
    console.log('pf.privateVar = '+pf.privateVar);
    console.log('pv.publicVar = '+pv.publicVar);
    console.log('pv.privateVar = '+pv.privateVar);
    

    注意PrivateFunc 不是PrivateFun。真正的因素归结为关键字thisthis 指的是当前对象,就像您键入 this 时一样。 var 只能在您的方法中访问。您应该将 JavaScript 对象视为关联数组。如果这不符合您的需求,请尝试:

    var jsObject = {
      publicVar: null,
      PrivateFun: function(private){
        var privateVar = private; //cannot access with dot
        return this;
      },
      PublicFun: function(public){
        this.publicVar = public;
        if(this.publicVar == null)this.publicVar = 'This is a public variable';
        return this;
      }
    }
    
    var pf = jsObject.PublicFun();
    var pv = jsObject.PrivateFun('private variable');
    console.log('pf.publicVar = '+pf.publicVar);
    console.log('pf.privateVar = '+pf.privateVar);
    console.log('pv.publicVar = '+pv.publicVar);
    console.log('pv.privateVar = '+pv.privateVar+' //cannot access with dot');
    

    请注意,对象文字不是构造函数,因此您不能创建 new 实例。此外,在 Object Literal 的情况下,var privateVar 实际上是无用的,除非您不希望返回 privateVar。必须返回 this 才能访问 jsObject,其中包含对 publicVar 的引用。

    【讨论】:

      猜你喜欢
      • 2015-02-12
      • 2016-02-25
      • 1970-01-01
      • 2015-11-08
      • 2017-09-14
      • 2014-12-27
      • 2013-10-17
      • 2014-09-08
      • 2021-07-04
      相关资源
      最近更新 更多