functionfakeParseJSON(str) {let i =0;functionparseObject() {if (str[i] ==='{') { i++;skipWhitespace();// if it is not '}',// we take the path of string -> whitespace -> ':' -> value -> ...while (str[i] !=='}') {constkey=parseString();skipWhitespace();eatColon();constvalue=parseValue(); } } }}
function fakeParseJSON(str) { let i = 0; function parseObject() { if (str[i] === '{') { i++; skipWhitespace();+ let initial = true; // if it is not '}', // we take the path of string -> whitespace -> ':' -> value -> ... while (str[i] !== '}') {+ if (!initial) { + eatComma();+ skipWhitespace();+ } const key = parseString(); skipWhitespace(); eatColon(); const value = parseValue();+ initial = false; } // move to the next character of '}' i++; } }}
function fakeParseJSON(str) { let i = 0; function parseObject() { if (str[i] === '{') { i++; skipWhitespace();+ const result = {}; let initial = true; // if it is not '}', // we take the path of string -> whitespace -> ':' -> value -> ... while (str[i] !== '}') { if (!initial) { eatComma(); skipWhitespace(); } const key = parseString(); skipWhitespace(); eatColon(); const value = parseValue();+ result[key] = value; initial = false; } // move to the next character of '}' i++;+ return result; } }}
既然你已经看到了我实现对象语法的过程,现在是时候尝试一下数组语法了:
functionfakeParseJSON(str) {// ...functionparseArray() {if (str[i] ==='[') { i++;skipWhitespace();constresult= [];let initial =true;while (str[i] !==']') {if (!initial) {eatComma(); }constvalue=parseValue();result.push(value); initial =false; }// move to the next character of ']' i++;return result; } }}
现在,看一个更有趣的语法,"value":
他是以一个"whitespace"开始,然后是任何可能的值:“string”, “number”, “object”, “array”, “true”, “false” or “null”,然后以"whitespace"来结束。
function fakeParseJSON(str) { // ... function parseObject() { // ...+ while (i < str.length && str[i] !== '}') { + // ...+ }+ checkUnexpectedEndOfInput(); // move to the next character of '}' i++; return result; }}
多做一些事
错误代码和标准的错误消息
下面这些是有用的关键字,会帮助用户出错之后去google定位。
// instead ofUnexpected token "a"Unexpected end of input// showJSON_ERROR_001 Unexpected token "a"JSON_ERROR_002 Unexpected end of input
更好的查看哪里出了问题
像Babel这样的解析器,将向您显示一个代码框架,带有下划线、箭头或突出显示错误的代码片段
// instead ofUnexpected token "a" at position 5// show{ "b"a^JSON_ERROR_001 Unexpected token "a"
打印出代码片段:
functionfakeParseJSON(str) {// ...functionprintCodeSnippet() {constfrom=Math.max(0, i -10);consttrimmed= from >0;constpadding= (trimmed ?3:0) + (i - from);constsnippet= [ (trimmed ?'...':'') +str.slice(from, i +1),' '.repeat(padding) +'^',' '.repeat(padding) + message, ].join('\n');console.log(snippet); }}
错误修正的建议
如果可能的话,解释出了什么问题,并给出解决问题的建议
// instead ofUnexpected token "a" at position 5// show{ "b"a^JSON_ERROR_001 Unexpected token "a".Expecting a ":" over here, eg:{ "b": "bar" }^You can learn more about valid JSON string in http://goo.gl/xxxxx
如果可能,根据解析器目前收集的上下文提供建议
fakeParseJSON('"Lorem ipsum');// instead ofExpecting a `"` over here, eg:"Foo Bar"^// showExpecting a `"` over here, eg:"Lorem ipsum"