啊啊啊啊啊我太菜了我要秃了,菜鸟前端少女自己写的可能会有隐藏bug,请谨慎阅读
JSON.stringfy()
function myStringfy(data){
// 字符串 >>> 自己
// 数字 >>> 自己
// undefined >>> 自己 (外面不加引号)
// null >>> 自己
// function >>> undefined (外面不加引号)
// 数组 >>> 用逗号分隔 如果某项为undefined 该项处记录为null
// 对象 >>> key 用双引号包起来, 各属性逗号分隔 筛选掉undefined
const myStringfyFunc = (data) => {
if( data === null || data === undefined || typeof(data) === 'string' || typeof(data) === 'number' ){
return data;
} else if( typeof(data) === 'function' ){
return undefined;
} else if(typeof(data) === 'object'){
if(Array.isArray(data)){ // 数组
return `[${
data.map(item=>{
if(myStringfyFunc(item) === undefined || item === null) return 'null';
else return myStringfyFunc(item);
}).join(',')
}]`
} else { // 对象
let arr = [];
for(let key in data){
if(myStringfyFunc(data[key]) !== undefined){
arr.push(`"${key}":${myStringfyFunc(data[key])}`);
}
}
return `{${arr.join(',')}}`
}
} else {
return new Exception('UNKNOWN TYPE!')
}
}
if(data === undefined || typeof(data) === 'function'){
return myStringfyFunc(data);
} else if(typeof(data) === 'string'){
return `"${myStringfyFunc(data)}"`
} else {
return `${myStringfyFunc(data)}`
}
}
测试方法
function test(data){
const res1 = JSON.stringify(data);
const res2 = myStringfy(data);
return {
passed: res1 === res2, // 对于多层嵌套的引用类型无法正确判断
input: data,
correct: res1,
yours: res2,
}
}
// console.log(test());
// console.log(test(''));
// console.log(test('123'));
// console.log(test(0));
// console.log(test(1111));
// console.log(test({a:111,b:null,c:undefined,d:function(){}}));
// console.log(test([1,2,null,undefined,function(){}]));
// console.log(test(null));
// console.log(test(undefined));
JSON.parse()
function myParse(str){
const err = ()=>{ throw new Error('WRONG JSON!') }
const indexStr = (str, sub)=>{
for(let i=0; i< str.length; i++){
if(str.substr(i,sub.length) === sub){
return i;
}
}
return -1;
}
const charStrCount = (str, char) => {
let count = 0;
for(let i = 0; i< str.length;i++){
if(str.charAt(i) === char) count++;
}
return count;
}
const letfPunc = ['[','{'];
// null >>> null
// number >>> 自己
// 非空字符串 >>> ↓
// 其他 >>> 报错
// ----非空字符串----
// 数字 (Number(a)!==NAN)
// 字符串 前后都是 ""
// null === 'null'
// 数组(过程中校验) [开头 ]结尾
// 对象(过程中校验) {开头 }结尾
if (str === null) return null;
else if (typeof(str) === 'number') return str;
else if (typeof(str) === 'string' && str !== ''){
if(!Number.isNaN(Number(str))) return Number(str);
else if( str.charAt(0) === '"' && str.charAt(str.length-1) === '"' && charStrCount(str, '"') === 2 ){
str = str.substring(0,str.length-1).substring(1)
return str;
} else if( str === 'null' ) return null;
else if(str.charAt(0) === '{' && str.charAt(str.length-1) === '}'){ // ----对象----
str = str.substring(0,str.length-1).substring(1);
const obj = {};
let propCount = 0;
while(str.length>0){
if(propCount>0){
if(str.charAt(0)!==',') err();
str = str.substring(1);
}
if(str.charAt(0) === '"'){
str = str.substring(1);
const keyEndIndex = indexStr(str,'"');
if(keyEndIndex>=0){
const key = str.substring(0,keyEndIndex);
str = str.substring(keyEndIndex+1);
if(str.charAt(0) === ':'){
str = str.substring(1);
// value可能是 null || 123 || "string" || [] || {}
if(indexStr(str, 'null')===0){ // null
obj[key] = null;
str = str.substring(4);
} else if(Number(str.charAt(0)>0) || (str.charAt(0) === '-'&&Number(str.charAt(1)))){ // number
let endIndex = 0;
for(let i=1; i<str.length; i++){
if(Number.isNaN(Number(str.charAt(i))) && str.charAt(i)!== '.'){
endIndex = i-1;
break;
}
}
const value = str.substring(0,endIndex+1);
if( typeof(Number(value)) === 'number'){
obj[key] = Number(value);
str = str.substring(endIndex+1);
} else {
err();
}
} else if(str.charAt(0) === '"'){ // string
str = str.substring(1);
const nextQuoIndex = indexStr(str,'"');
if(nextQuoIndex>=0){
obj[key] = str.substring(0,nextQuoIndex);
str = str.substring(nextQuoIndex+1);
}
} else if(letfPunc.indexOf(str.charAt(0))>=0){ // object || array
const temp = [];
for(let i=0; i<str.length; i++){
const current = str.charAt(i);
if(letfPunc.indexOf(current)>=0){
temp.push(current);
} else if(current === '}'){
if(temp.pop() !== '{') err();
} else if(current === ']'){
if(temp.pop() !== '[') err();
} else if(current === ','){
if(temp.length === 0) {
obj[key] = myParse(str.substring(0, i));
str = str.substring(i);
break;
}
}
if(i === str.length-1){
if(temp.length === 0){ // 最后一个属性 不会遇到逗号打断
obj[key] = myParse(str);
str = '';
} else err();
}
}
} else err();
propCount++;
} else err();
} else err()
} else err();
}
return obj;
} else if(str.charAt(0) === '[' && str.charAt(str.length-1) === ']'){
str = str.substring(0,str.length-1).substring(1);
const arr = [];
while(str.length>0){
if(arr.length>0){
if(str.charAt(0)!==',') err();
str = str.substring(1);
}
// 数组元素可能是 null || 123 || "string" || [] || {}
if(indexStr(str, 'null')===0){ // null
arr.push(null);
str = str.substring(4);
} else if(Number(str.charAt(0)>0) || (str.charAt(0) === '-'&&Number(str.charAt(1)))){ // number
let endIndex = 0;
for(let i=1; i<str.length; i++){
if(Number.isNaN(Number(str.charAt(i))) && str.charAt(i)!== '.'){
endIndex = i-1;
break;
}
}
const value = str.substring(0,endIndex+1);
if( typeof(Number(value)) === 'number'){
arr.push(Number(value))
str = str.substring(endIndex+1);
} else err();
} else if(str.charAt(0) === '"'){ // string
str = str.substring(1);
const nextQuoIndex = indexStr(str,'"');
if(nextQuoIndex>=0){
arr.push(str.substring(0,nextQuoIndex))
str = str.substring(nextQuoIndex+1);
}
} else if(letfPunc.indexOf(str.charAt(0))>=0){ // object || array
const temp = [];
for(let i=0; i<str.length; i++){
const current = str.charAt(i);
if(letfPunc.indexOf(current)>=0){
temp.push(current);
} else if(current === '}'){
if(temp.pop() !== '{') err();
} else if(current === ']'){
if(temp.pop() !== '[') err();
} else if(current === ','){
if(temp.length === 0) {
arr.push(myParse(str.substring(0, i)));
str = str.substring(i);
break;
}
}
if(i === str.length-1){
if(temp.length === 0){ // 最后一个元素 不会遇到逗号打断
console.log(str)
arr.push(myParse(str));
str = '';
} else err();
}
}
} else err();
}
return arr;
} else {
};
} else err();
}
测试程序
function testMyParse(data){
const res1 = JSON.parse(data);
const res2 = myParse(data);
return {
passed: res1 === res2, // 对于多层嵌套的引用类型无法正确判断
input: data,
correct: res1,
yours: res2,
}
}
// console.log(testMyParse(null));
// console.log(testMyParse(1));
// console.log(testMyParse(-1.7888));
// console.log(myParse(undefined));
// console.log(myParse(''));
// console.log(myParse('"'));
// console.log(testMyParse('"1233"'));
console.log(testMyParse('{"a":1,"c":null,"d":"dgaiuhgraui","e":[1,2,3,4,{"a":7}]}'));
console.log(testMyParse('[-134,{"b":-78,"c":"hush/..,d,,,:","e":[]},"jduifh{}[{}]",1]'));