【问题标题】:Javascript extend class with props?Javascript用道具扩展类?
【发布时间】:2013-11-14 17:14:37
【问题描述】:

我的类定义为:

function MyClass() {

}

MyClass.prototype = {
       init: function() {
                 alert('My parent class!');
       },
       method1: function() {},
       method2: function() {}
};

和属性对象:

{
     init: function() {
               MySubClass.superclass.init.apply(this, arguments);
               alert('test!');
     },

     test: function() {
               alert();
     }
}

我需要一个函数,它将用道具(对象)扩展基类(MyClass)并返回新的扩展子类(到 MySubClass):

MySubclass = extend(MyClass, {
     init: function() {
               MySubClass.superclass.init.apply(this, arguments);
               alert('test!');
     },

     test: function() {
               alert();
     }
});

构造函数必须被新的构造函数替换(来自 init)。

我需要一个正确的方法。

为什么效果不好?

extend: function(bc, o) {
        // result class (apply only first constructor)
        var cls = function() {};
        cls.prototype = bc.prototype;

        for (var k in o)
            cls.prototype[k] = o[k];

        cls.superclass = bc.prototype;

        return cls;
    }

【问题讨论】:

    标签: javascript jquery class oop


    【解决方案1】:

    您的 extend 函数必须看起来像这样 - 现在这比您应该如何真正实现它要简单得多,但它应该可以工作:

    var extend = function(Super, props) {
       var sinstance = new Super()
       var sclass = props.constructor || sinstance.constructor;
       sclass.prototype.super = sinstance;
       sclass.prototype.constructor = Super;
    
       //use underscore extend prototypes cause im too lazy to type it out
       _.extend(sclass.prototype, sinstance, props);
       return sclass;
    }
    

    调用subclass.super.call(this, props...) 允许您访问被覆盖的超级方法。

    刚刚测试过,如果页面上有下划线js,这可以工作:

    function MyClass() {
    
    }
    MyClass.prototype = {
           init: function() {
                     alert('My parent class!');
           },
           method1: function() {},
           method2: function() {}
    };
    
    MySubclass = extend(MyClass, {
         init: function() {
                   this.super.init.apply(this, arguments);
                   alert('test!');
         },
    
         test: function() {
                   alert();
         }
    });
    
    var test = new MySubclass();
    test.init("yo"); //alerts My parent class
    

    对于您的更新,您也可以这样做:

    MySubclass2 = extend(MyClass, {
         constructor: function() {
            this.init();
         },
    
         init: function() {
                   this.super.init.apply(this, arguments);
                   alert('test!');
         },
    
         test: function() {
                   alert();
         }
    });
    
    var test2 = new MySubclass2();//alerts My parent class
    

    【讨论】:

    • 我认为 $.extend 也可以工作,但我不记得该方法的语法
    • new Super() 将调用基类的构造函数,但我需要用子类方法替换类构造函数。
    • 好吧,从你的例子我假设你想使用 super 构造函数。您需要将扩展​​函数传递给我刚刚更新答案的版本的函数
    • 你想替换构造函数?如MyClass = otherCtor?
    • 我只想从 props 对象中替换所有内容,包括函数中的构造函数。
    【解决方案2】:

    如果您愿意使用库,请使用来自underscore.js 的 _.extend。否则,将此代码添加到您的代码库中:

    extend = function(obj) {
        each(slice.call(arguments, 1), function(source) {
          if (source) {
            for (var prop in source) {
              obj[prop] = source[prop];
            }
          }
        });
        return obj;
      };
    

    【讨论】:

    • 这是面向对象的编程,而 MyClass 不是对象。 MyClass 是我想用对象扩展的函数。
    • @xercool MyClass 实际上是一个对象,尽管它是一个 Function 对象。仅供参考
    【解决方案3】:

    我看到您使用 jQuery 进行了标记 - 如果您确实在使用 jQuery,您可能对使用 $.extend 感兴趣。

    【讨论】:

    • 感谢@Max,我很高兴有些理智!由于这个原因,$.extend 是我一直使用的最常用的 jquerie 插件。
    【解决方案4】:

    看看这个:https://github.com/haroldiedema/joii

    var BaseClass = function() 
    {
        this.some_var = "foobar";
    
        /**
         * @return string
         */
        this.someMethod = function() {
            return this.some_var;
        }
    };
    
    var MyClass = new Class({ extends: BaseClass }, function()
    {
        /**
         * @param string value
         */
        this.__construct = function(value)
        {
            this.some_var = value;
        }
    
    })
    

    用法:

    var obj = new MyClass("Hello World!");
    console.log( obj.someMethod() ); // Hello World!
    

    【讨论】:

      猜你喜欢
      • 2013-02-18
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 2021-03-07
      • 2011-01-16
      • 2017-11-21
      • 1970-01-01
      相关资源
      最近更新 更多