【问题标题】:Inheritance in nested namespaces in JavaScriptJavaScript 中嵌套命名空间的继承
【发布时间】:2013-03-03 08:12:55
【问题描述】:

我想设置嵌套命名空间来组织我的代码。我正在尝试遵循this article 中描述的类似插件的结构。问题是我不明白如何在我的示例中访问this.error_msg。我设置正确了吗?我是否必须使用 jQuery .extend.prototype 才能访问 this.error_msg

(function(TC, $, undefined){

    TC.ajax = function() {
        this.error_msg = 'default error...';         
    };

    TC.ajax.run = function(){
        //do stuff...
        TC.ajax.handle_error();
    };

    TC.ajax.handle_error = function(){
        alert(this.error_msg);
    };        

}(window.TC = window.TC || {}, jQuery));

// Test it
TC.ajax.run();

演示:http://jsfiddle.net/g99yt/

【问题讨论】:

    标签: javascript jquery namespaces scope javascript-namespaces


    【解决方案1】:

    我认为您的代码必须如下所示:

    (function(TC, $, undefined){
        _this = this;
        TC.ajax = function() {
            _this.error_msg = 'default error...';         
        };
    
        TC.ajax.run = function(){
            //do stuff...
            TC.ajax.handle_error();
        };
    
        TC.ajax.handle_error = function(){
            alert(_this.error_msg);
        };        
    
    }(window.TC = window.TC || {}, jQuery));
    
    // Test it
    TC.ajax.run();
    

    【讨论】:

    • 这行得通,但我试图避免 error_msg 在范围内成​​为全局(在 TC 下)。我希望它只能从 TC.ajax 和嵌套在它下面的函数访问。所以当我写this.error_msg 时,我的意思是TC.ajax.error_msg。到目前为止,我似乎需要为此使用原型,正如 Evan 所描述的那样......除非你知道另一种方式?
    【解决方案2】:

    要记住的重要一点是,每次使用 function() 时,都会创建一个新范围。因此,您可以在 TC.ajax.handle_error 方法中看到 this.error_msg 未定义,因为您尚未在该范围内定义它。您可以做的一件事是创建原型以确保这些方法与您的 ajax 对象相关联并声明该对象的新实例,然后在其上调用您的方法。见下文:

    (function(TC, $, undefined){
    
        TC.ajax = function() {
            this.error_msg = 'default error...';         
        };
    
        TC.ajax.prototype.run = function(){
            //do stuff...
            this.handle_error.call(this);
        };
    
        TC.ajax.prototype.handle_error = function(){
            alert(this.error_msg);
        };        
    
    }(window.TC = window.TC || {}, jQuery));
    
    // Test it
     var ajaxInstance = new TC.ajax();
    
    ajaxInstance.run();
    

    还有fiddle

    您确实有其他选择,例如像 @kta 那样保留一个局部全局变量,或者通过 call 函数设置您的范围,但这并不适用于您的结构。

    【讨论】:

    • 与其他解决方案不同,这可以很好地保持范围。添加必须创建实例的步骤很糟糕,但我理解为什么需要这样做。
    • 很高兴我能帮上忙。如果您打算更深入地学习面向对象的 javascript,那么开始实践创建实例可能是个好主意
    【解决方案3】:

    如果TC.ajax 应该是构造函数,则需要将run()handle_error() 添加到原型中。

    但你可以做类似的事情

    TC.ajax = {};    
    TC.ajax.error_msg = 'default error...'; 
    

    在您的情况下,只要您调用 TC.ajax()error_msg 就会被分配给 this,这永远不会发生。即使那样,this 也会引用TC。而当TC.ajax.handle_error()被调用时,this指的是TC.ajax

    【讨论】:

      【解决方案4】:

      这实际上是一个常见问题,目前尚不清楚this 指的是什么。所以解释一下:

      TC.ajax.handle_error = function(){
          alert(this.error_msg);
      };   
      

      TC.ajax.handle_error 函数中的 this 指的是函数,而不是您的 TC 对象。 所以只需保存对TC 的引用,以便您以后参考:

      var _this = this;
      
      ...
      _this.error_msg = 'default error....';
      ...
      
      TC.ajax.handle_error = function(){
           alert(_this.error_msg);
       };        
      

      【讨论】:

      • 嗯,但我试图引用 TC.ajax.error_msg,而不是 TC.error_msg。这将如何适用于该范围?
      • @Justin 抱歉,我会澄清答案,TC 具有 error_message 作为属性,因此对 TC 的引用允许您访问 TC.error_msg
      【解决方案5】:

      这是我最终使用的:

      (function ($, TC, undefined) {
      
          TC.nestedNamespace = TC.nestedNamespace || {};
      
          //add a public function to our new namespace 
          TC.nestedNamespace.test = function () {        
             console.log("Winning!");    
          };
      
      }(jQuery, window.TC = window.TC || {}));
      
      TC.nestedNamespace.test();
      

      例如JSFiddle。我在related article的cmets中找到了这个方法。

      【讨论】:

        猜你喜欢
        • 2013-03-10
        • 1970-01-01
        • 1970-01-01
        • 2013-08-13
        • 2017-12-10
        • 1970-01-01
        • 2011-01-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多