• 插件写法(基于继承)


    /**
     * @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);
  • 相关阅读:
    Maven的安装与配置(eclipse,idea)
    用java代码打印九九乘法表
    HDFS的Java客户端操作代码(HDFS删除文件或目录)
    Java代码操作HDFS(在/user/root/下面創建目錄)
    第二种方式读取并显示HDFS中的内容
    HDFS的java客户端操作代码(Windows上面打jar包,提交至linux运行)
    HDFS的Java客户端操作代码(HDFS的查看、创建)
    CentOs6.8安装Git并安装oh my zsh
    搭建maven开发环境测试Hadoop组件HDFS文件系统的一些命令
    R-大数据分析挖掘(5-R基础回顾)
  • 原文地址:https://www.cnblogs.com/qianduanjingying/p/6165241.html
Copyright © 2020-2023  润新知