在 JAVASCRIPT module模式中定义私有字段成员和继承

IT技术 javascript oop inheritance private-members module-pattern
2021-02-21 15:09:46

我可以使用以下代码在module模式中定义私有成员字段

    var myClass = function(){
       var private_field1,private_field_2;
       var private_func1 = function(){
            //.......
       } 
       //.........
       var myObj = {
         global_field1:2,
         global_field2:"something",
         global_func: function(){//......} 
       }
       return myObj;
    };
   var obj = myClass();

这种方法工作得很好,但这个问题的问题在于,每当我创建一个新对象时,所有函数的副本都会被创建并加载到内存中(不像 java 中同一类的所有对象共享相同的函数内存)

我尝试使用以下其他方法:

 var myClass = (function(){
           var private_field1,private_field_2;//private static fields
           var private_func1 = function(){
                //.......
           } 
           //.........
           var Constr = function(){
             //do something
           }
           Constr.prototype = {
             //................
             global_func: function(){//......} 
           }
           return Constr;
    }());
var obj1 = new myClass();
var obj2 = new myClass();

但这种方法的问题在于,显然 obj1、obj2 共享相同的私有字段副本(因此它们实际上是静态的)。那么有没有办法在module模式中定义私有字段,同时为对象使用相同的函数副本?

对于上面提到的第一种方法的继承,我首先需要在子类中创建一个对象,然后返回该对象。

 var ChildClass = function(){
      var childobj = myClass();
      //override or add functions to childobj
      return childobj ;
 }

但这实际上只是将 baseClass 的对象包装在 childClass 中,是否有其他方法可以实现相同的(对于第一种或第二种方法),以便它可以像真正的 java 继承一样使用受保护、私有等方法?

1个回答

不可以。JavaScript 中的私有性只能通过作用域(并从中导出:闭包)来完成。

那些需要访问私有变量(和函数)的函数,称为特权方法,需要在构造函数中定义。那些没有的方法(只与公共属性或其他方法交互)应该在原型对象上定义,所以你最终会得到一个混合的方法。可能与您刚刚发现的静态值结合使用。

顺便说一句,不是函数 [code] 本身被多次复制和记忆。只需要存储不同范围的对象(词法环境)。

继承通常不是通过创建父对象并扩展它们来完成的,而是通过创建子实例并像父对象一样扩展它们来完成的。这可以通过父级的构造函数应用于新创建的子级来完成:

function ChildClass() {
    ParentClass.call(this, /* … arguments */);

    // usual body, using "this"
}

此外,Child 的原型直接从 Parent 的原型对象继承。这可以通过Object.create完成(需要为旧浏览器填充):

ChildClass.prototype = Object.create(ParentClass.prototype, {
    constructor: {value:ChildClass}
});
第一种方法这么有效?
2021-05-02 15:09:46
是的 - 虽然我会创建完整的实例而不是返回对象文字。
2021-05-13 15:09:46
....call如果您返回对象,继承将不起作用(仅举个例子)
2021-05-19 15:09:46