zoukankan      html  css  js  c++  java
  • 原生JS的对象常用操作总结

       前端时间写了篇怎么判断js对象相等的文章,一直在期待大神给点消息,无奈一直杳无音讯,还是自己写个函数来进行判断,下面总结一些常用的对象操作的方法。

       咋们来个先抑后扬的方式,先放出几个基本的东西,埋点伏笔,一下子就把那方法亮出来,我这文章就没得写了。大神们就绕道走吧,哥这是入门级别的,自己觉还挺实用的,就先做个记录。

    类型定义及判断

      先来个全局变量 及定义默认的数据类型

       1:    var framework = {
       2:      //定义常用的js类型
       3:        type : {
       4:            nothing : -1,
       5:            undefined : 0,
       6:            string : 1,
       7:            number : 2,
       8:            array : 3,
       9:            regex : 4,
      10:            bool : 5,
      11:            method : 6,
      12:            datetime : 7,
      13:            object : 8
      14:        },
      15:      types:{},
      16:      addType:function(type,compare){
      17:        framework.types[type]=compare
      18:      }
      19:    };
      20:    
      21:      //默认的数据类型判断
      22:       framework.addType(framework.type.nothing, function (value) {
      23:           return value == null;
      24:       });
      25:       framework.addType(framework.type.array, function (value) {
      26:           return value instanceof Array;
      27:       });
      28:       framework.addType(framework.type.string, function (value) {
      29:           return value.substr && value.toLowerCase;
      30:       });
      31:       framework.addType(framework.type.number, function (value) {
      32:           return value.toFixed && value.toExponential;
      33:       });
      34:       framework.addType(framework.type.regex, function (value) {
      35:           return value instanceof RegExp;
      36:       });
      37:       framework.addType(framework.type.bool, function (value) {
      38:           return value == true || value == false;
      39:       });
      40:       framework.addType(framework.type.method, function (value) {
      41:           return value instanceof Function;
      42:       });
      43:       framework.addType(framework.type.datetime, function (value) {
      44:           return value instanceof Date;
      45:       });

      哥本来还担心没啥东西,一贴这点代码就有点心虚了,有兴趣的悠着点耐心点,后面估计还有段距离呀。。。。下面开始进入主题吧。

    先上两个小菜

       废话就不多说了,直接贴代码,这个应该是个人都能看懂的哈,不解释。。。

       1:    framework.util = {
       2:      //转换成字符串
       3:        toString : function (val) {
       4:            return val == null ? "" : val.toString();
       5:        },
       6:      
       7:      //去除字符串首尾空格
       8:        trim : function (value) {
       9:            value = value == null ? "" : value;
      10:            value = value.toString();
      11:            return value.replace(/^s*|s*$/g, "");
      12:        },
      13:        getType : function (obj) {
      14:            
      15:            if (obj == null) {
      16:                return framework.type.nothing;
      17:            }
      18:            for (var item in framework.types) {
      19:                if (framework.types[item](obj)) {
      20:                    return item;
      21:                }
      22:            }
      23:          //不匹配已定义的默认类型,就返回object
      24:            return framework.type.object;
      25:        },
      26:        isType : function (type, value) {
      27:            return framework.util.getType(value) == type;
      28:        }
      29:    }
      30:    菜上完了,先尝下合不合口啊,敲代码习惯性敲一点验证下,这样改起来能够比较快捷的定位到问题在哪。
       1:   var log =console.log;
       2:     log(framework.util.getType(null));         // -1  nothing
       3:     log(framework.util.getType("aaa"));        // 1   string
       4:     log(framework.util.getType(framework));    // 8  object
       5:     log(framework.util.getType(function(){})); //6    method
       6:     log(framework.util.getType(3232));         //2    number
       7:     log(framework.util.getType([]));           //3    array
       8:     log(framework.util.getType(true));         //5    bool
       9:     log(framework.util.getType(new Date()));   //7    datetime
     
           比较幸运的一次性通过了,没敲错字母,看好了,要发力了。我觉得还是一次性上完算了。别拖拖拉拉的了。
           这里直接贴util 对象中的方法啦。不重复贴上面的代码,测试的自己合并一下就可以了。
     
       1:      //遍历集合对象
       2:        each : function (collection, action) {
       3:            var index = 0;
       4:            for (var item in collection) {
       5:                if (collection.hasOwnProperty(item))
       6:                    action(collection[item], index++);
       7:            }
       8:        },
       9:        
      10:        clone : function (obj) {
      11:            //判断是否是数组,是数组克隆每一项
      12:            if (framework.util.isType(framework.type.array, obj)) {
      13:                return framework.util.cloneArray(obj);
      14:            }
      15:            //克隆对象中的值
      16:            else if (framework.util.isType(framework.type.object, obj)) {
      17:                var clone = {};
      18:                for (var item in obj) {
      19:                    if (obj.hasOwnProperty(item)) //去掉原型链中的属性
      20:                        clone[item] = framework.util.clone(obj[item]);
      21:                }
      22:                return clone;
      23:            }
      24:            //如果是其他类型,则直接返回其值
      25:            else {
      26:                return obj;
      27:            }
      28:        },
      29:   
      30:        //进行数组克隆
      31:        cloneArray : function (array) {
      32:            var result = [];
      33:            framework.util.each(array, function (item) {
      34:                result.push(framework.util.clone(item));
      35:            });
      36:            return result;
      37:        },
      38:   
      39:        //路径转换
      40:        getPath : function (path) {
      41:            return framework.util.toString(path).split(framework.exp.get_path);
      42:        },
      43:   
      44:        //创建句柄执行函数
      45:        invoke : function (obj, args) {
      46:            args = args.concat();
      47:   
      48:            var path = args[0];
      49:            var method = framework.util.findValue(obj, path);
      50:            args = framework.util.select(args, null, 1, null);
      51:   
      52:            path = path.replace(/..*$/, "");
      53:            var parent = framework.util.findValue(obj, path);
      54:            obj = parent === method ? obj : parent;
      55:            try {
      56:                var result = method.apply(obj, args);
      57:                return result;
      58:            } catch (e) {
      59:                return null;
      60:            }
      61:        },
      62:   
      63:        //根据路径找值
      64:        findValue : function (obj, path) {
      65:            if (framework.util.isType(framework.type.array, path)) {
      66:                return this.util.invoke(obj, path);
      67:   
      68:            } else if (framework.util.isType(framework.type.string, path)) {
      69:                path = framework.util.getPath(path);
      70:                var index = 0;
      71:                while (obj != null && index < path.length) {
      72:                    obj = obj[path[index++]];
      73:                }
      74:                return obj;
      75:   
      76:            } else {
      77:                return obj;
      78:            }
      79:        },
      80:        //对象转换成数组
      81:        toArray : function (obj) {
      82:            var items = [];
      83:            if (obj.length) {
      84:                for (var i = 0; i < obj.length; i++) {
      85:                    items.push(obj[i]);
      86:                }
      87:            } else {
      88:                for (var item in obj) {
      89:                    if (obj.hasOwnProperty(item))
      90:                        items.push(obj[item]);
      91:                }
      92:            }
      93:            return items;
      94:        },
      95:        equals : function (val1, val2) {
      96:             //深度判断对象相等,这个是重点呀,那天就是为了这个东西纠结我老半天,现在都还在纠结中,一直没找到好的方法解决。
      97:            if (framework.util.getType(val1) == framework.util.getType(val1) && framework.util.isType(framework.type.array, val1)) {
      98:                return framework.util.arrayEquals(val1, val2);
      99:            } else if (framework.util.getType(val1) == framework.util.getType(val1) && framework.util.isType(framework.type.object, val1)) {
     100:                var result = true;
     101:                for (var item in val1) {
     102:                    if (framework.util.isType(framework.type.array, val1[item])) {
     103:                        result = framework.util.arrayEquals(val1[item], val1[item]);
     104:                    } else {
     105:                        result = (val1[item] == val2[item]);
     106:                    }
     107:                    if (result == false)
     108:                        break;
     109:                }
     110:                return result;
     111:            } else {
     112:                return val1 == val2;
     113:            }
     114:   
     115:        },
     116:        arrayEquals : function (val1, val2) {
     117:            if (framework.util.isType(framework.type.array, val1) && framework.util.isType(framework.type.array, val2) && val1.sort().toString() == val2.sort().toString()) {
     118:                return true;
     119:            } else {
     120:                return false;
     121:            }
     122:   
     123:        },
     124:        //返回索引所在的值
     125:        elementAt : function (collection, index) {
     126:            return collection && collection.length > 0 && index < collection.length && index >= 0
     127:             ? collection[index]
     128:             : null;
     129:        },
     130:   
     131:        //向目标对象附加属性
     132:        apply : function (target, source) {
     133:            for (var item in source) {
     134:                if (source.hasOwnProperty(item))
     135:                    target[item] = source[item];
     136:            }
     137:            return target;
     138:        },
     139:   
     140:        //获取at后面的值
     141:        remaining : function (array, at) {
     142:            var results = [];
     143:            for (; at < array.length; at++)
     144:                results.push(array[at]);
     145:            return results;
     146:        },
     147:   
     148:        regexEscape : function (val) {
     149:            return (val ? val : "").toString().replace(framework.exp.escape_regex, "\$&");
     150:        },
     151:   
     152:        //正则匹配搜索
     153:        regexMatch : function (expression, source, ignoreCase) {
     154:   
     155:            if (this.util.isType(framework.type.regex, expression)) {
     156:                expression = expression.source;
     157:            }
     158:   
     159:            expression = new RegExp(framework.util.toString(expression), ignoreCase ? "gi" : "g");
     160:            return framework.util.toString(source).match(expression) != null;
     161:        }

                 这个大餐是上完了,验证下有没有效果吧。先上个简单的,出错了免得出丑。

       1:      var a =new People(12,"abc");
       2:      var b = a;
       3:      var c = framework.util.clone(a);
       4:      log(b==a);   //true
       5:      log(c==a);   //false
       6:      log(c);      //当然别忘了验证下值是否相等。
    最后证明还是可行的,当然这个不是重点,重点在下面,能不能进行深度克隆,这里为People 添加一个属性
     
       2:      var a =new People(12,"abc",[12,"bb"]);
       3:      var b = a;
       4:      var c = framework.util.clone(a);
       5:      log(b==a);   //true
       6:      log(c==a);   //false
       7:      log(c);      //当然别忘了验证下值是否相等。   

              log(a.child==c.child);            //false ==判断是对象的引用是否相等,所以这里为false ,本来是想要true的,看下面的语句:
              log( framework.util.equals(a,c))  //true   这里返回的是我所想要的结果。
     

      在这里其他的函数就不一一展示了,如果感兴趣的自己验证下结果。
    另这个 深度 判断相等并没有做到完美,在数组中存在的对象如果顺序调换下,还是会判断为false ,哪位如果有好的方法可以帮我改进一下。
             最好能做到如下两个结果是相等的。。
             a={id:5,name:"dd",[12,value:{id:8,name:”dd”}]}
             b={name:”dd”,id:5,[12,value:{name:”dd”,id:8}]}
          
  • 相关阅读:
    LeetCode: Longest Valid Parentheses 解题报告
    LeetCode: Generate Parentheses 解题报告
    Leetcode: LRU Cache 解题报告
    LeetCode: Maximal Rectangle 解题报告
    LeetCode: Min Stack 解题报告
    LeetCode: Restore IP Addresses 解题报告
    LeetCode: Longest Common Prefix 解题报告
    LeetCode: Regular Expression Matching 解题报告
    Python——rrdtool模块的安装
    python-xlsxwriter模块绘制表格
  • 原文地址:https://www.cnblogs.com/stell/p/3194358.html
Copyright © 2011-2022 走看看