Javascript类创建脚本的优缺点?

Javascript类创建脚本的优缺点?,javascript,jquery,class,Javascript,Jquery,Class,我最近编写了一个类创建脚本(在Crockford和Resig针对某些部分的代码的帮助下),该脚本自动化了某些任务,例如:将默认值与传入的参数合并,需要参数,在DOM和类实例之间创建桥梁,用公共名称空间绑定自定义事件,通过访问超级方法继承,以及混合的能力 我的第一个问题是,以这种方式创建类的利弊是什么?我关心的是性能和可移植性(我所有的类现在都依赖于这个脚本) 我的第二个问题是,编写类创建脚本的更好方法是什么?代码如下 (function($){ // Crockford's way of cre

我最近编写了一个类创建脚本(在Crockford和Resig针对某些部分的代码的帮助下),该脚本自动化了某些任务,例如:将默认值与传入的参数合并,需要参数,在DOM和类实例之间创建桥梁,用公共名称空间绑定自定义事件,通过访问超级方法继承,以及混合的能力

我的第一个问题是,以这种方式创建类的利弊是什么?我关心的是性能和可移植性(我所有的类现在都依赖于这个脚本)

我的第二个问题是,编写类创建脚本的更好方法是什么?代码如下

(function($){
// Crockford's way of creating new objects
function F(){};
function _createObject(o) {
    F.prototype = o;
    return new F();
};

$.Class = function(){
    var
        prototype = {}
        ,_super = {}
        ,requiredError = ''
        ,extendedInits = []
        ,fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

    // copy properties/methods to prototype
    for (var i = 0, ln = arguments.length; i < ln; ++i){
        var obj = arguments[i];

        // if extending another class
        if ($.isFunction(obj)) _super = obj = obj.prototype;

        if (typeof obj == 'object'){
            for (var prop in obj){
                var objMethod = obj[prop];

                // Resig's Simple Javascript Inheritance
                // if method already exists, map old method to this._super()
                prototype[prop] = typeof objMethod == "function" && typeof _super[prop] == "function" && fnTest.test(obj[prop]) ?
                    (function(prop, fn){
                      return function() {
                        var tmp = this._super;

                        // Add a new ._super() method that is the same method
                        // but on the super-class
                        this._super = _super[prop];

                        // The method only need to be bound temporarily, so we
                        // remove it when we're done executing
                        var ret = fn.apply(this, arguments);
                        this._super = tmp;

                        return ret;
                      };
                    })(prop, objMethod) :
                    // or overwrite the method/property
                    objMethod;

                // if __init method is defined on any of the objects passed in, they will be automatically run at instantiation
                if (prop == '__init') extendedInits.push(obj[prop]);
            }
        }
    }

    prototype.__initialize = function(){
        var
            self = this
            ,dataNS = this.__dataNS
            ,requiredParams = this.__requiredParams;

        // check required parameters
        if (requiredParams){
            for (var i = 0, ln = requiredParams.length; i < ln; ++i){
                var param = requiredParams[i];
                if (arguments.length == 0 || !arguments[0][param]) requiredError = requiredError + param + ', ';
            }
        }

        // if all required params are passed in
        if (requiredError.length == 0){
            // set defaults
            this.cfg = $.extend(true, {}, this.__defaults, arguments[0]);
            this.$elem = this.cfg.$elem;

            // create bridge between dom and instance
            if (dataNS) this.$elem.data(dataNS, this);

            // init class instance
            if (this.init) this.init.apply(this, arguments);

            // init objects instance was extended with
            if (extendedInits.length > 0){
                $.each(extendedInits, function(k, fn){
                    fn.apply(self, arguments);
                });
            }

            // init instance level 
            if (this.cfg.__init) this.cfg.__init.apply(this, arguments);
        }
        else {
            // alert missing properties
            requiredError = requiredError.substring(0, requiredError.lastIndexOf(','));
            var str = 'Required Parameters: ' + requiredError;
            if (dataNS) str = dataNS + ' - ' + str;
            alert(str);
        }
    };

    function _Class(){
        this.__initialize.apply(this, arguments);
    }

    _Class.prototype = _createObject(prototype);
    _Class.constructor = _Class;

    return _Class;
}
})(jQuery);

注意:$。上面示例中的ClassUtils是一组混合到$中的公共方法。Accordion类

很多框架都会像您所做的那样。我主要关心的是,它试图使javascript成为它所不具备的东西。Javascript是原型继承语言。它不是一种经典的继承语言

这并不是说“类管理”库没有用处,因为它们是有用的。您的一些反馈:您编写的其他代码示例使创建类变得更容易。如果要这样做,创建类时的最终结果应该是

var myObj =  MyStuff.create({
   prop: prop,
   doSomething: function(){}
 });

从你的例子中我可以看出,这比你所使用的系统更容易阅读,也更不容易打字……

很多框架都是你所做的。我主要关心的是,它试图使javascript成为它所不具备的东西。Javascript是原型继承语言。它不是一种经典的继承语言

这并不是说“类管理”库没有用处,因为它们是有用的。您的一些反馈:您编写的其他代码示例使创建类变得更容易。如果要这样做,创建类时的最终结果应该是

var myObj =  MyStuff.create({
   prop: prop,
   doSomething: function(){}
 });

从你的例子中我可以看出,这比你设置的系统更容易阅读,也更不容易键入…

Hm我可能遗漏了一些东西,但你的代码片段与我的第二个代码片段不一样吗?您的示例是定义类本身,而不是实例化一个,对吗?我见过其他实现使用类似Class.create({})的东西,但我喜欢使用新操作符(如果只是出于语义原因)。@alex,啊,我明白你的意思了。如何扩展类?它类似于var extendedClass=new$.class(thisClassJson、classToExtendFrom、secondClassToExtendFrom);所以基本上,传入的第一个json被用作该类的定义,而其他每个json都是混合的。我可能遗漏了一些东西,但您的代码段与我的第二个代码段不相似吗?您的示例是定义类本身,而不是实例化一个,对吗?我见过其他实现使用类似Class.create({})的东西,但我喜欢使用新操作符(如果只是出于语义原因)。@alex,啊,我明白你的意思了。如何扩展类?它类似于var extendedClass=new$.class(thisClassJson、classToExtendFrom、secondClassToExtendFrom);所以基本上,传入的第一个json被用作该类的定义,而其他的json都被混入其中