Javascript static / singelton - 这与vs _this vs对象名称

时间:2014-11-03 20:34:25

标签: javascript jquery oop this encapsulation

这是关于表现和最佳实践的问题。

假设我有一个封装了大量辅助方法的js对象。该对象被视为静态类,这意味着它永远不会被实例化,并且它的所有方法基本上都是辅助方法。 使用事件和jQuery时,对象的this范围不断变化,因为它有相当多的方法,我想知道什么是最佳做法 - 将this保存到_this }在每个方法的开头或简单地使用对象名MyObject

多年来,我一直在做两件事,当涉及到singelton /静态物体时,但我认为必须有一个最佳实践,并且关于采用最佳方法的时间。

我目前的研究表明,使用_this代替直接调用MyObject所带来的好处主要是这两个:

  • 如果对象的名称发生更改,_this将始终有效
  • 可能更快(虽然没有看到性能测试结果),因为浏览器保持在相同的范围内,并且不需要每次都找到MyObject的范围。

使用MyObject的优点:

  • 少写代码。
  • 垃圾收集管理? (减去要分配的变量)
  • 对于某些开发人员来说可能更具可读性(多个this适用)
  • 更容易重构代码,因为MyObject将始终有效

我想知道是否有一种全局保存_this的方法(仅在对象的范围内),并避免在每个方法的开头分配它。如果没有 - 是否存在我缺少的其他优点/缺点,或者直接调用对象名称被认为是不好的做法。

这是一个简化的参考对象(真实对象有更多方法)。

    var MyObject = {
       init: function() {

         this.registerEvents();
         //other stuff

       },
       registerEvents: function() {

         this.registerOnSomeEvent();
         //registering more events..
         //...

       },

       registerOnSomeEvent: function() {
          var _this = this;
          jQuery('#someid').click(function() {
             _this.doSomething();//option 1
             MyObject.doSomething();//option 2
          });
       },

       doSomething: function() {
         //doing something...
       }
    }

MyObject.init();

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

您可以将整个对象封装在闭包中以实现此目的,而无需在每个函数上指定_this

window.MyObject = (function () {
    var self = {
        init: function() {

            self.registerEvents();
            //other stuff

        },
        registerEvents: function() {

            self.registerOnSomeEvent();
            //registering more events..
            //...

        },

        registerOnSomeEvent: function() {
            jQuery('#someid').click(function() {
                self.doSomething();//option 1
                self.doSomething();//option 2
            });
        },

        doSomething: function() {
            //doing something...
        }
    };

    self.init();

    return self;
})();

答案 1 :(得分:3)

我认为你的问题是,你需要花费很长时间来模仿你应该做的事情。

const mySingleton = (function () {
    // Instance stores a reference to the Singleton 
    var instance;
    function init() {
        // Singleton
        // Private methods and variables
        var privateVariable = "Im also private";
        var privateRandomNumber = Math.random();

        return {
            // Public methods and variables
            publicMethod: function () {
                console.log( "The public can see me!" );
            },
            publicProperty: "I am also public",
            get randomNumber() {
                return privateRandomNumber;
            }
         };
         function privateMethod(){
            console.log( "I am private" );
         }

     };
     return {
         // Get the Singleton instance if one exists
         // or create one if it doesn't
         get instance() {
             if ( !instance ) instance = init();
             return instance;
         }
     };   
})();

如果您不想使用this上下文,请永远不要使用继承,并且永远不要有多个实例,只是不要将这些内容写为对象上的方法,而是将声明的私有方法写入a singleton pattern(这是一个揭示模块模式,但只有一个实例)

因为它本身就是基本上完全如此,但你揭示了所有内容,并且你完全没有任何目的地发送了数百次数百{}}垃圾邮件。设计this 不是常量。不要这样使用它。