es6学习5: util方法封装

let mm = {
    /**
     * 判断各种对象类型是否相等
     * @param a [比较方a]
     * @param b [比较方b]
     * @returns {boolean}
     */
    isEqual(a, b) {
        //如果a和b本来就全等
        if (a === b) {
            //判断是否为0和-0
            return a !== 0 || 1 / a === 1 / b;
        }
        //判断是否为null和undefined
        if (a == null || b == null) {
            return a === b;
        }
        //接下来判断a和b的数据类型
        let classNameA = toString.call(a),
            classNameB = toString.call(b);
        //如果数据类型不相等,则返回false
        if (classNameA !== classNameB) {
            return false;
        }
        //如果数据类型相等,再根据不同数据类型分别判断
        switch (classNameA) {
            case '[object RegExp]':
            case '[object String]':
                //进行字符串转换比较
                return '' + a === '' + b;
            case '[object Number]':
                //进行数字转换比较,判断是否为NaN
                if (+a !== +a) {
                    return +b !== +b;
                }
                //判断是否为0或-0
                return +a === 0 ? 1 / +a === 1 / b : +a === +b;
            case '[object Date]':
            case '[object Boolean]':
                return +a === +b;
        }

        //如果是对象类型
        if (classNameA == '[object Object]') {
            //获取a和b的属性长度
            let propsA = Object.getOwnPropertyNames(a),
                propsB = Object.getOwnPropertyNames(b);
            if (propsA.length != propsB.length) {
                return false;
            }
            for (let i = 0; i < propsA.length; i++) {
                let propName = propsA[i];
                //如果对应属性对应值不相等,则返回false
                if (a[propName] !== b[propName]) {
                    return false;
                }
            }
            return true;
        }
        //如果是数组类型
        if (classNameA == '[object Array]') {
            if (a.toString() == b.toString()) {
                return true;
            }
            return false;
        }
    },

    /**
     * 对象深拷贝
     * @param data
     * @returns {any}
     */
    objDeepCopy(data) {
        return JSON.parse(JSON.stringify(data));
    },
    copyProperties :function(target,source){
        for(let key of Reflect.ownKeys(source)){
            if(key!=='constructor'&&key!=='prototype'&&key!=='name'){
                let desc=Object.getOwnPropertyDescriptor(source,key);
                Object.defineProperty(target,key,desc);
            }
        }
    },
    /**
     * 多重继承, 可以用建造者模式去设计程序
     * @param {classA, classB, classC} mixins
     * @returns {Mix}
     * 使用指南
     * // 定义A
     * class A {
            init_A(){
                this.dream_A = '轮子滚动了';
                this.leg_A = 'leg';
                return this;
            }
            roll_A(){
                console.log(this.dream_A);
                return this;
            }
     }
     // 定义B
     class B {
            init_B(){
                this.dream_B = 'dreamB';
                return this;
            }
            doSth_B() {
                console.log(this.dream_B);
            }
     }
     // 定义类并多重继承
     class D extends mm.mix(A,B) {
     }
     // 组装
     let car = new D().init_A().init_B();
     // 调用
     car.roll_A();
     car.doSth_B();
     */
    mix: function(...mixins){
        class Mix{}
        for(let mixin of mixins){
            this.copyProperties(Mix,mixin);
            this.copyProperties(Mix.prototype,mixin.prototype);
        }
        return Mix
    },
    /**
     * // Match反复匹配
     * @param str [要匹配的字符串]
     * @param reg [匹配的正则]
     * @returns {arry}
     */
    matchAll(str, reg) {
        let result = [];
        if (reg.flags.indexOf('g') === -1) {
            console.error('ERROR: 正则中请加入全局修饰符g');
            return;
        }
        let match;
        let n = 0;
        while (match = reg.exec(str)) {
            result.push(match);
        }
        return result;
    },

    /**
     *   得到浏览器query参数
     * @param name
     * @returns {any}
     */
    getUrlParam: function (name) {
        // 例如检索出 happymmall.com/product/list?keyword=xxx&page=1 每个参数值
        let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
        // window.location.search 就是 ?keyword=xxx&page=1这段参数
        let result = window.location.search.substr(1).match(reg);
        // 如果有值进行解码
        return result ? decodeURIComponent(result[2]) : null;
    },
    // 增加一些选择器
    setSelectMethod() {
        /**
         * 选择兄弟元素, 同jq的siblings
         * @param callback
         * @returns {Array}
         */
        Element.prototype.siblings = function (callback) {
            let siblingElement = [];
            let parentAllElement = [];
            if (!this.parentNode) {
                return siblingElement;
            }
            // 限定在元素下
            parentAllElement = this.parentNode.getElementsByTagName(this.tagName);
            for (let i = 0, iLen = parentAllElement.length; i < iLen; i++) {
                if (parentAllElement[i] != this) {
                    siblingElement.push(parentAllElement[i]);
                    typeof callback == "function" && callback.call(parentAllElement[i]);
                }
            }
            return siblingElement;
        };

    },
    /**
     * 增加一些个人方法
     */
    setMethod() {
        /**
         * 给数组元素批量
         * @param {string} className [要添加的类名]
         * @returns {Array} 用来链式调用
         */
        Array.prototype.addClass = function (className) {
            let len = this.length;
            for (let i = 0, iLen = this.length; i < iLen; i++) {
                this[i].classList.add(className);
            }
            return this;
        };

        /**
         * 数组批量移除类名
         * @param className
         * @returns {Array}
         */
        Array.prototype.removeClass = function (className) {
            let len = this.length;
            for (let i = 0, iLen = this.length; i < iLen; i++) {
                this[i].classList.remove(className);
            }
            return this;
        };

        /**
         * 批量切换类的有无
         * @param className
         * @returns {Array}
         */
        Array.prototype.toggleClass = function (className) {
            let len = this.length;
            for (let i = 0, iLen = this.length; i < iLen; i++) {
                this[i].classList.toggle(className);
            }
            return this;
        };

        /**
         * 添加类
         * @param className
         * @returns {Element}
         */
        Element.prototype.addClass = function (className) {
            this.classList.add(className);
            return this;
        };

        /**
         * 移除某个类
         * @param className
         * @returns {Element}
         */
        Element.prototype.removeCLass = function (className) {
            this.classList.remove(className);
            return this;
        };

        /**
         * 切换类的有无
         * @param className
         * @returns {Element}
         */
        Element.prototype.toggleClass = function (className) {
            this.classList.toggle(className);
            return this;
        };

        /**
         * 判断是否包含某个类
         * @param className
         * @returns {boolean}
         */
        Element.prototype.hasClass = function (className) {
            return this.classList.contains(className);
        };

        /**
         * 去除所有空格
         * @returns {string}
         */
        String.prototype.trimAll = function () {
            return this.replace(/\s*/g, '')
        };

        /**
         * 编码html字符串, 防止XSS攻击
         * @returns {string}
         */
        String.prototype.escapeHTML = function () {
            return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        };

        /**
         * 解码html字符串
         * @returns {string}
         */
        String.prototype.unEscapeHTML = function () {
            return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
        };

        /**
         * 得到数据类型名(开头字母大写)  如[] -> Array
         * 使用:  let a = []   a.getType()
         * @returns {string}
         */
        Object.prototype.getType = function () {
            return toString.call(this).match(/^\[object\s(\w*)(\])$/)[1];
        };
    }
};

export default mm;

 

posted @ 2018-12-08 15:07  颜繁达  阅读(821)  评论(0编辑  收藏  举报