【问题标题】:Constructor or init function for an object对象的构造函数或初始化函数
【发布时间】:2012-03-05 11:46:42
【问题描述】:

我正在为以下情况寻找构造函数或初始化函数:

var Abc = function(aProperty,bProperty){
   this.aProperty = aProperty;
   this.bProperty = bProperty;
}; 
Abc.prototype.init = function(){
   // Perform some operation
};

//Creating a new Abc object using Constructor.

var currentAbc = new Abc(obj,obj);

//currently I write this statement:
currentAbc.init();

有没有办法在新对象初始化时调用init函数?

【问题讨论】:

    标签: javascript oop


    【解决方案1】:

    你可以在构造函数中调用init()

    var Abc = function(aProperty,bProperty){
       this.aProperty = aProperty;
       this.bProperty = bProperty;
       this.init();
    }; 
    

    这是一个小提琴演示:http://jsfiddle.net/CHvFk/

    【讨论】:

    • 我在这种模式中看到的缺点是 init 是公共的。它可以像 a.init() 一样调用。通常初始化函数是私有的。因此,最好在构造函数中定义它。见fiddle update
    【解决方案2】:

    2020 年更新

    虽然在回答这个问题时,JavaScript 中的类还没有广泛使用,但现在情况已不再如此。 Most major browsers now support the ES2015 class syntax,随着 JavaScript 转译器的流行,它为那些不支持它的环境提供向后兼容性,类现在使用起来相当安全,并且对于那些从常见 OOP 语言转向 JavaScript 的人来说看起来更自然。

    ES2015 类版本

    class Abc {
      constructor (aProperty, bProperty) {
        this.aProperty = aProperty;
        this.bProperty = bProperty;
    
        this.init();
      }
    
      init () {
        // Initialization code here.
      }
    }
    
    let currentAbc = new Abc(obj, obj);
    

    私有版本与之前的版本大致相同,因为新类语法中没有提供可见性关键字

    class Abc {
      constructor (aProperty, bProperty) {
        this.aProperty = aProperty;
        this.bProperty = bProperty;
    
        this.init = function () {
          // Initialization code here.
        }
    
        this.init();
      }
    }
    
    let currentAbc = new Abc(obj, obj);
    

    还有在闭包中创建类的选项,我相信一些编译器可能会这样做以确保函数在运行时是私有的。

    const Abc = (function() {
      function privateInit () {
        // Do initialization here
      }
    
      return class Abc {
        constructor (aProperty, bProperty) {
          this.aProperty = aProperty;
          this.bProperty = bProperty;
    
          privateInit.call(this);
        }
      };
    })();
    
    const currentAbc = new Abc(obj, obj);
    

    如果您使用的是 TypeScript 等超集,您可以简单地私下实现 init 函数,尽管这只是编译器检查,因此它可以保护您免受您自己的影响,而不是外部代码。

    class Abc {
      aProperty: any;
      bProperty: any;
    
      constructor (aProperty: any, bProperty: any) {
        this.aProperty = aProperty;
        this.bProperty = bProperty;
    
        this.init();
      }
    
      private init () {
        // Initialization code here.
      }
    }
    
    let currentAbc = new Abc(obj, obj);
    

    原答案

    也许是这样的?

    var Abc = function(aProperty,bProperty){
        this.aProperty = aProperty;
        this.bProperty = bProperty;
        this.init = function(){
            // Do things here.
        }
        this.init();
    }; 
    var currentAbc = new Abc(obj,obj);
    

    【讨论】:

    • 这是正确的,你必须在定义它之后调用init()函数。
    【解决方案3】:

    如果你的 init 方法应该保持私有:

    var Abc = function(aProperty,bProperty){
       function privateInit(){ console.log(this.aProperty);}   
       this.aProperty = aProperty;
       this.bProperty = bProperty;
    
       privateInit.apply(this);
    };
    

    我更喜欢这个。

    【讨论】:

      【解决方案4】:

      这个怎么样?

      var Abc = function(aProperty,bProperty){
          this.aProperty = aProperty;
          this.bProperty = bProperty;
      
          //init
          (function () {
              // Perform some operation
          }.call(this));
      }; 
      var currentAbc = new Abc(obj,obj);
      

      【讨论】:

        【解决方案5】:

        为什么不把 init 函数中的东西放到 cunstructor 中,像这样:

        var Abc = function(aProperty,bProperty){
            this.aProperty = aProperty;
            this.bProperty = bProperty;
        
            // Perform some operation
        
        }; 
        

        【讨论】:

        • 为什么要使用函数?减少代码的冗余和模块化。这就是为什么我想要它作为一个函数。
        • 绝对不是应该被否决的评论。事实上,您几乎总是只调用一次构造函数,而您的函数将不会超过 #region 语句。
        【解决方案6】:

        构造函数应该是初始化实例的地方。如果不应该重新运行 init 方法,请将与初始化相关的代码保留在构造函数中,而是将代码拆分为多个特定的子方法(最好是私有的),如果它变得又大又乱。

        也就是说,如果您需要重新运行或“异步”调用 init 方法,我认为最灵活的解决方案是从您的 init 方法返回 this。这样您就可以创建一个实例,将其分配给一个变量,然后在一行中调用您仍然独立的 init 方法。

        var Abc = function(aProperty){
           this.aProperty = aProperty;
        };
        Abc.prototype.init = function(){
          // init stuff
          return this;
        };
        // either as oneliner
        var abc = new Abc().init();
        // or 
        var abc = new Abc();
        setTimeout(function(){abc.init()},500);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-09-10
          • 1970-01-01
          • 2021-11-06
          • 1970-01-01
          • 1970-01-01
          • 2012-08-14
          • 2013-12-30
          相关资源
          最近更新 更多