js 实现JSON.stringify 转化加格式化

34 篇文章 0 订阅
29 篇文章 0 订阅
//输入:
var data = {
  a: 1,
  b: [2, 3, {
    c: 4
  }],
  d: {
    e: 5,
    f: {
      g: '6'
    },
  }
}
//输出:
"{
  "a": 1,
  "b": [
      2,
      3,
      {
          "c": 4
      }
  ],
  "d": {
      "e": 5,
      "f": {
          "g": "6"
      }
  }
}"

JSON.stringify的一些规则以及注意点:当对象为数字,null,boolean的时候,直接转换为相应的字符串就可以了。 但是string,function,undefined,object,array等,需要特殊处理。

1.undefined,该类型使用JSON.stringify处理的时候,如果对象就是undefined,将会输出"undefined",如果对象是数组的元素,那么将会变成null,比如:[undefined],stringify之后变成了"[null]";如果该对象是object的元素,那么该属性将当作不存在,不输出,比如{a:1,b:undefined},stringify之后是"{\"a\":1},B属性直接抛弃。

2.字符串在拼接的时候需要把内部的双引号处理掉

(function(NS){ 
  
  //简单类型 
  var simpleTypes = ["number", "boolean", "undefined", "string", "function"]; 
    
  //JSON.stringify的主函数 
  function stringify(object){ 
   var type = typeof object; 
     
   //如果是简单类型,则直接返回简单类型的结果 
   if(indexOf(simpleTypes, type) > -1){ 
    return parseSimpleObject(object); 
   } 
   
   //数组对象的 
   if(object instanceof Array){ 
    var len = object.length; 
    var resArr = []; 
    for(var i = 0; i < len; i++){ 
     var itemType = typeof object[i]; 
     if(indexOf(simpleTypes, itemType) > -1){ 
   
      //undefined特殊处理,数组中变成null 
      if(itemType != "undefined"){ 
       resArr.push(parseSimpleObject(object[i])); 
      }else{ 
       resArr.push("null"); 
      } 
        
     }else{ 
      //递归处理JS数组中的复杂元素 
      resArr.push(stringify(object[i])); 
     } 
    } 
      
    return "[" + resArr.join(",") + "]"; 
   } 
     
   //普通object对象 
   if(object instanceof Object){ 
    if(object == null){ 
     return "null"; 
    } 
      
    var resArr = []; 
      
    for(var name in object){ 
     var itemType = typeof object[name]; 
     if(indexOf(simpleTypes, itemType) > -1){ 
      //undefined特殊处理,object中不编码 
      if(itemType != "undefined"){ 
       resArr.push("\"" + name + "\":" + parseSimpleObject(object[name]));  
      } 
     }else{ 
      resArr.push("\"" + name + "\":" + stringify(object[name])); 
     } 
    } 
      
    return "{" + resArr.join(",") + "}"; 
   } 
  } 
    
  function parseSimpleObject(object){ 
   var type = typeof object; 
   if(type == "string" || type == "function"){ 
    return "\"" + object.toString().replace("\"", "\\\"") + "\""; 
   } 
     
   if(type == "number" || type == "boolean"){ 
    return object.toString(); 
   } 
     
   if(type == "undefined"){ 
    return "undefined"; 
   } 
     
   return "\"" + object.toString().replace("\"", "\\\"") + "\""; 
  } 
    
  function indexOf(arr, val){ 
   for(var i = 0; i < arr.length; i++){ 
    if(arr[i] === val){ 
     return i; 
    } 
   } 
     
   return -1; 
  } 
    
  /** 
   * 将stringify做二次封装 
   * @param object 要处理的对象 
   * 
   */
  NS.stringify = function(object, isEncodeZh){ 
   var res = stringify(object); 
   if(isEncodeZh){ 
    var encodeRes = ""; 
    for(var i = 0; i < res.length; i++){ 
     if(res.charCodeAt(i) < 0xff){ 
      encodeRes += res[i]; 
     }else{ 
      encodeRes += "\\u" + res.charCodeAt(i).toString(16); 
     } 
    } 
    res = encodeRes; 
   } 
     
   return res; 
  }; 
 })(window);
  function repeat(s, count) {
    return new Array(count + 1).join(s)
  }
  function formatJson(json) {
    var i = 0,
      il = 0,
      tab = "    ",
      newJson = "",
      indentLevel = 0,
      inString = false,
      currentChar = null;
    for (i = 0, il = json.length; i < il; i += 1) {
      currentChar = json.charAt(i);
      switch (currentChar) {
        case '{':
        case '[':
          if (!inString) {
            newJson += currentChar + "\n" + repeat(tab, indentLevel + 1);
            indentLevel += 1
          } else {
            newJson += currentChar
          }
          break;
        case '}':
        case ']':
          if (!inString) {
            indentLevel -= 1;
            newJson += "\n" + repeat(tab, indentLevel) + currentChar
          } else {
            newJson += currentChar
          }
          break;
        case ',':
          if (!inString) {
            newJson += ",\n" + repeat(tab, indentLevel)
          } else {
            newJson += currentChar
          }
          break;
        case ':':
          if (!inString) {
            newJson += ": "
          } else {
            newJson += currentChar
          }
          break;
        case ' ':
        case "\n":
        case "\t":
          if (inString) {
            newJson += currentChar
          }
          break;
        case '"':
          if (i > 0 && json.charAt(i - 1) !== '\\') {
            inString = !inString
          }
          newJson += currentChar;
          break;
        default:
          newJson += currentChar;
          break
      }
    }
    return newJson
  }

测试:

var res = stringify(data);
var res2 = formatJson(res);

console.log(res2);
//对象转化成json串的精简版本
 function json2str(o) {
  let arr = [];
  const fmt = function(s) {
      if (typeof s == 'object' && s !== null) return json2str(s);
      return /^(string)$/.test(typeof s) ? `"${s}"`: s;
  }
  for (var i in o) arr.push(`"${i}": ${fmt(o[i])}`);
  return`{${arr.join(',')}}`
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值