2013-07-25 25 views
3

我正在使用John Resig的简单OOP Class,它适合于使用“严格使用”并取自SO post
在所有的例子我看到的Class.extend使用像这样:简单的JavaScript OOP类

var MyObj = Class.extend({ 
    init:function(){}, 
    prop: "Property" 
}); 

但是我发现了一个大缺点,我在这样的方式使用它 - 我不能有“私人”的变量,所以我不能存储参考this like var $this = this;。 我发现我的情况的解决方案,现在我在下面的方式使用Class.extend

var MyObj = Class.extend(new function(){ 
    var $this = this; 
    this.init = function(){}; 
    this.prop = "Property"; 
}); 

一切都在我的情况下工作,但我想知道是否有一些事情,可能会导致我的问题,从长远来看?
这样做我的应用程序会消耗更多的浏览器内存?
我有什么替代方法来实现我的需求?

注意:我需要存储$这一点,因为我使用大量的事件和回调,所以我想引用“原始” this易于访问的对象的所有方法和属性。

编辑:按照要求,这是我的代码示例:

(function() { 
    "use strict"; 
    window.QuickPlay = Class.extend(new function() { 
     var $this = this; 

     this.init = function (initData) { 
      $this.elementsToHide.push(initData.el); 
      $(function() { 
       playProcessStart(); 
       Sys.Application.add_load(function() { 
        $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { $this.setElementsVisibility(""); }); 
       }); 
       $this.setElementsVisibility("hidden"); 
      }); 
     }; 

     this.elementsToHide = []; 

     this.setElementsVisibility = function (visibility) { 
      $.each($this.elementsToHide, function (i) { 
       $("#" + this).css("visibility", visibility); 
      }); 
     }; 
    }); 
}()); 
+3

Ouch,no。我几乎不能相信这对你真的很有用。请告诉我们你如何使用这个具有事件和回调的“类”。也许发布你的实际代码(至少涉及'$ this'的方法)。 – Bergi

+0

@Bergi我添加了这个例子 - 这真的很有效,代码已经通过了QA阶段:) –

+0

在任何对象的内部,你都应该能够访问'this'这个reefers到当前对象。 – travis

回答

1

我不能有 “私有” 变量

当然,你可以。在(目前不需要的)(function() { … }());包装器中,或者在你的构造函数中(init的东西)。

new function() { 

Avoid that pattern!如果你真的需要你的代码工作像现在一样,使用

(function() { 
    "use strict"; 
    // Here's the place where you could put a private, static variable 
    // for example `var elementsToHide = [];` 
    var $this = { 
     init: function (initData) { 
      $this.elementsToHide.push(initData.el); 
      $(function() { 
       playProcessStart(); 
       Sys.Application.add_load(function() { 
        $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { 
         $this.setElementsVisibility(""); 
        }); 
       }); 
       $this.setElementsVisibility("hidden"); 
      }); 
     }, 
     elementsToHide: [], 
     setElementsVisibility: function (visibility) { 
      $.each($this.elementsToHide, function (i) { 
       $("#" + this).css("visibility", visibility); 
      }); 
     } 
    }; 
    window.QuickPlay = Class.extend($this); 
}()); 

我想知道,如果有一些事情,可能会导致我的问题

是的。多个实例很难工作,因为它们都参考相同的elementsToHide数组。而且你没有使用任何实例方法(只有你的类的构造函数和静态元素),所以类模式似乎是不必要的。改为使用a module。如果您需要单个实例(和类),代码应如下所示:

"use strict"; 

window.QuickPlay = Class.extend({ 
    init: function (initData) { 
     var $this = this; 
     this.elementsToHide = []; 
     $(function() { 
      playProcessStart(); 
      $this.elementsToHide.push(document.getElementById(initData.el)); 
      Sys.Application.add_load(function() { 
       $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { 
        $this.setElementsVisibility(""); 
       }); 
      }); 
      $this.setElementsVisibility("hidden"); 
     }); 
    }, 
    setElementsVisibility: function (visibility) { 
     $(this.elementsToHide).css("visibility", visibility); 
    } 
}); 
+0

感谢您以我使用Class的方式指向“巨大”问题......在我的应用程序中,我需要使用“singletons”和Classes,所以看起来我需要使用/ create每种情况都有两种不同的模式。目前我刚刚在项目中开始使用JS OOP,所以现在还没有太晚的时间来改变这些东西:) –

+0

你能指点我一个好模式如何创建一个需要使用创建数据初始化的“模块”? –

+0

我会认为单身模块非常静态,没有“创建”。我可以想到a)将数据编码到模块代码中b)模块从全局“数据存储器”中获取数据本身c)全局控制器通过调用数据的“init”方法“启动”模块参数。请参阅我已链接代码结构模式的Osmani文章。 – Bergi

2

您可以使用模块模式,并保持所有的OOP。这些模式为您的代码提供了更高的安全性和更好的组织性。在JsFiddle

  • 如何与继承和模块模式工作

    //these are namespaces in javascript 
    window.project = window.project || {}; //this kind declarations prevents recreate the object 
    project.group = project.group || {}; 
    
    //in the line below we can use $ instead jQuery, and use window and document instead ask for the browser every time. 
    (function (window, document, $) { 
        "use strict"; 
    
        project.group.NameOfYourModule = function() { 
         var privateAttribute = true, 
          students = 32, //It's is a best practice declare everything in an unique var. 
    
          privateMethod = function() { 
           alert('Now I know OOP using jQuery'); 
          }; 
    
         return { 
          init: function() { 
           //this is a public method and we can initiate some private method; 
           privateMethod(); 
    
           //we call a public method using this 
           this.publicMethod(); 
          }, 
          publicMethod: function() { 
           //this is a public method 
          } 
         }; 
        }; 
    
        $(function() { 
         var myclass = new project.group.NameOfYourModule(); //instantiate you class 
         myclass.init(); //initiate some public method 
        }); 
    }(window, document, jQuery)); 
    
  • +0

    它看起来很不错,但是继承呢?如何在你的模式中创建MySecondModule继承自NameOfYourModule?Class为我提供了它 –

    +0

    我添加了参考exaplaining它是如何工作的继承。很高兴能帮到:) –

    +0

    谢谢,我看到了链接...我确信它可以工作,但对其他团队成员来说太复杂:(我正在尝试一些易于使用的东西... –