• 插件写法(基于继承)


    /**
     * @author: xiangliang.zeng
     * @description:
     * @Date: 2016/12/12 16:57
     * @Last Modified by:   xiangliang.zeng
     * @Last Modified time: 2016/12/12 16:57
     */
    
    (function(factory) {
        var root = (typeof self == "object" && self.self == self && self) || (typeof global == "object" && global.global == global && global);
        if (typeof define == "function" && define.amd) {
            define(['exports'], function(exports) {
                root.Example == factory(root, exports);
            });
        } else if (typeof exports !== 'undefined') {
            factory(root, exports);
        } else {
            root.Example = factory(root, {});
        }
    })(function(root, Example) {
        //initializing用于控制类的初始化,非常巧妙,请留意下文中使用技巧
        //fnTest返回一个正则比表达式,用于检测函数中是否含有_super,这样就可以按需重写,提高效率。当然浏览器如果不支持的话就返回一个通用正则表达式
        var initializing = false, fnTest = /xyz/.test(function() {xyz;}) ? /_super/ : /.*/;
        //所有类的基类Class,这里的this一般是window对象
        Example.Class = function() {};
        //对基类添加extend方法,用于从基类继承
        Example.Class.extend = function(prop) {
            //保存当前类的原型
            var _super = this.prototype;
            //创建当前类的对象,用于赋值给子类的prototype,这里非常巧妙的使用父类实例作为子类的原型,而且避免了父类的初始化(通过闭包作用域的initializing控制)
            initializing = true;
            var prototype = new this();
            initializing = false;
            //将参数prop中赋值到prototype中,这里的prop中一般是包括init函数和其他函数的对象
            for (var name in prop) {
                //对应重名函数,需要特殊处理,处理后可以在子函数中使用this._super()调用父类同名构造函数, 这里的fnTest很巧妙:只有子类中含有_super字样时才处理从写以提高效率
                prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                    (function(name, fn) {
                        return function() {
                            //_super在这里是我们的关键字,需要暂时存储一下
                            var tmp = this._super;
                            //这里就可以通过this._super调用父类的构造函数了
                            this._super = _super[name];
                            //调用子类函数
                            fn.apply(this, arguments);
                            //复原_super,如果tmp为空就不需要复原了
                            tmp && (this._super = tmp);
                        }
                    })(name, prop[name]) : prop[name];
            }
            //当new一个对象时,实际上是调用该类原型上的init方法,注意通过new调用时传递的参数必须和init函数的参数一一对应
            function Class() {
                if (!initializing && this.init) {
                    this.init.apply(this, arguments);
                }
            }
    
            //给子类设置原型
            Class.prototype = prototype;
            //给子类设置构造函数
            Class.prototype.constructor = Class;
            //设置子类的extend方法,使得子类也可以通过extend方法被继承
            Class.extend = arguments.callee;
            return Class;
        }
    
    
        Example.Test1 = Example.Class.extend({
            init: function() {
                this.name = 'lily';
                this.age = 19;
            },
            sayName: function() {
                console.log('name======' + this.name);
            },
            sayAge: function() {
                console.log('age=====' + this.age);
            }
        });
    
        Example.Test2 = Example.Test1.extend({
            init: function() {
                this.same = 'face';
                this._super();   // 继承了Test1的属性
            },
            saySame: function() {
                console.log('saySame====' + this.same);
            }
        })
        return Example;
    });
    
    var test1 = new Example.Test1();
    test1.sayName();
    
    var test2 = new Example.Test2();
    test2.sayAge();
    console.log(test1);
    console.log(test2);

    写法二(个人感觉好一点):

    /**
     * @author: xiangliang.zeng
     * @description:
     * @Date: 2016/12/12 16:57
     * @Last Modified by:   xiangliang.zeng
     * @Last Modified time: 2016/12/12 16:57
     */
    
    (function(factory) {
        var root = (typeof self == "object" && self.self == self && self) || (typeof global == "object" && global.global == global && global);
        if (typeof define == "function" && define.amd) {
            define(['exports'], function(exports) {
                root.Example == factory(root, exports);
            });
        } else if (typeof exports !== 'undefined') {
            factory(root, exports);
        } else {
            root.Example = factory(root, {});
        }
    })(function(root, Example) {
        //initializing用于控制类的初始化,非常巧妙,请留意下文中使用技巧
        //fnTest返回一个正则比表达式,用于检测函数中是否含有_super,这样就可以按需重写,提高效率。当然浏览器如果不支持的话就返回一个通用正则表达式
        var initializing = false, fnTest = /xyz/.test(function() {xyz;}) ? /_super/ : /.*/;
        //所有类的基类Class,这里的this一般是window对象
        Example.Class = function() {};
        //对基类添加extend方法,用于从基类继承
        Example.Class.extend = function(prop) {
            //保存当前类的原型
            var _super = this.prototype;
            //创建当前类的对象,用于赋值给子类的prototype,这里非常巧妙的使用父类实例作为子类的原型,而且避免了父类的初始化(通过闭包作用域的initializing控制)
            initializing = true;
            var prototype = new this();
            initializing = false;
            //将参数prop中赋值到prototype中,这里的prop中一般是包括init函数和其他函数的对象
            for (var name in prop) {
                //对应重名函数,需要特殊处理,处理后可以在子函数中使用this._super()调用父类同名构造函数, 这里的fnTest很巧妙:只有子类中含有_super字样时才处理从写以提高效率
                prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                    (function(name, fn) {
                        return function() {
                            //_super在这里是我们的关键字,需要暂时存储一下
                            var tmp = this._super;
                            //这里就可以通过this._super调用父类的构造函数了
                            this._super = _super[name];
                            //调用子类函数
                            fn.apply(this, arguments);
                            //复原_super,如果tmp为空就不需要复原了
                            tmp && (this._super = tmp);
                        }
                    })(name, prop[name]) : prop[name];
            }
            //当new一个对象时,实际上是调用该类原型上的init方法,注意通过new调用时传递的参数必须和init函数的参数一一对应
            function Class() {
                if (!initializing && this.init) {
                    this.init.apply(this, arguments);
                }
            }
    
            //给子类设置原型
            Class.prototype = prototype;
            //给子类设置构造函数
            Class.prototype.constructor = Class;
            //设置子类的extend方法,使得子类也可以通过extend方法被继承
            Class.extend = arguments.callee;
            return Class;
        }
        return Example;
    });
    
    Example.Test1 = Example.Class.extend({
        init: function() {
            this.name = 'lily';
            this.age = 19;
        },
        sayName: function() {
            console.log('name======' + this.name);
        },
        sayAge: function() {
            console.log('age=====' + this.age);
        }
    });
    
    Example.Test2 = Example.Test1.extend({
        init: function() {
            this.same = 'face';
            this._super();
        },
        saySame: function() {
            console.log('saySame====' + this.same);
        }
    })
    
    var test1 = new Example.Test1();
    test1.sayName();
    
    var test2 = new Example.Test2();
    test2.sayAge();
    console.log(test1);
    console.log(test2);

     优化之后:

    /**
     * @author: xiangliang.zeng
     * @description:
     * @Date: 2016/12/12 16:57
     * @Last Modified by:   xiangliang.zeng
     * @Last Modified time: 2016/12/12 16:57
     */
    
    (function(factory) {
        "use strict";
        var root = (typeof self === "object" && self.self === self && self) || (typeof global === "object" && global.global === global && global);
        if (typeof define === "function" && define.amd) {
            define(['exports'], function(exports) {
                root.Example === factory(root, exports);
            });
        } else if (typeof exports !== 'undefined') {
            factory(root, exports);
        } else {
            root.Example = factory(root, {});
        }
    })(function(root, Example) {
        //initializing用于控制类的初始化,非常巧妙,请留意下文中使用技巧
        //fnTest返回一个正则比表达式,用于检测函数中是否含有_super,这样就可以按需重写,提高效率。当然浏览器如果不支持的话就返回一个通用正则表达式
        var initializing = false, fnTest = /xyz/.test(function() {return xyz;}) ? /_super/ : /.*/;
        //所有类的基类Class,这里的this一般是window对象
        Example.Class = function() {};
        //对基类添加extend方法,用于从基类继承
        Example.Class.extend = function(prop) {
            //保存当前类的原型
            var _super = this.prototype;
            //创建当前类的对象,用于赋值给子类的prototype,这里非常巧妙的使用父类实例作为子类的原型,而且避免了父类的初始化(通过闭包作用域的initializing控制)
            initializing = true;
            var prototype = new this();
            initializing = false;
            // - 则重新定义此方法
            function fn(name, fun) {
                return function() {
                    // 将实例方法_super保护起来。
                    // 个人觉得这个地方没有必要,因为每次调用这样的函数时都会对this._super重新定义。
                    var tmp = this._super;
                    // 在执行子类的实例方法name时,添加另外一个实例方法_super,此方法指向父类的同名方法
                    this._super = _super[name];
                    // 执行子类的方法name,注意在方法体内this._super可以调用父类的同名方法
                    var ret = fun.apply(this, arguments);
                    this._super = tmp;
                    // 返回执行结果
                    return ret;
                };
            }
            //将参数prop中赋值到prototype中,这里的prop中一般是包括init函数和其他函数的对象
            for (var name in prop) {
                if (prop.hasOwnProperty(name)) {
                    //对应重名函数,需要特殊处理,处理后可以在子函数中使用this._super()调用父类同名构造函数, 这里的fnTest很巧妙:只有子类中含有_super字样时才处理从写以提高效率
                    prototype[name] = typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) ?
                        fn(name, prop[name]) : prop[name];
                }
            }
            //当new一个对象时,实际上是调用该类原型上的init方法,注意通过new调用时传递的参数必须和init函数的参数一一对应
            function Class() {
                if (!initializing && this.init) {
                    this.init.apply(this, arguments);
                }
            }
    
            //给子类设置原型
            Class.prototype = prototype;
            //给子类设置构造函数
            Class.prototype.constructor = Class;
            //设置子类的extend方法,使得子类也可以通过extend方法被继承
            Class.extend = arguments.callee;
            return Class;
        };
        return Example;
    });
    
    Example.Test1 = Example.Class.extend({
        init: function() {
            this.name = 'lily';
            this.age = 19;
        },
        sayName: function() {
            console.log('name======' + this.name);
        },
        sayAge: function() {
            console.log('age=====' + this.age);
        }
    });
    
    Example.Test2 = Example.Test1.extend({
        init: function() {
            this.same = 'face';
            this._super();
        },
        saySame: function() {
            console.log('saySame====' + this.same);
        }
    });
    
    var test1 = new Example.Test1();
    test1.sayName();
    
    var test2 = new Example.Test2();
    test2.sayAge();
    console.log(test1);
    console.log(test2);
  • 相关阅读:
    设计模式学习总结系列应用实例
    【研究课题】高校特殊学生的发现及培养机制研究
    Linux下Oracle11G RAC报错:在安装oracle软件时报file not found一例
    python pro practice
    openstack python sdk list tenants get token get servers
    openstack api
    python
    git for windows
    openstack api users list get token get servers
    linux 流量监控
  • 原文地址:https://www.cnblogs.com/qianduanjingying/p/6165241.html
Copyright © 2020-2023  润新知