【前端三分钟】写一个JSON.Parse解析器

简介: 【前端三分钟】写一个JSON.Parse解析器


//使用递归降序法
let JsonParse = function() {
    let at, //当前字符索引
      ch, //当前字符
      escapee = {
        '"': '"',
        '\\': '\\',
        '/': '/',
        b: 'b',
        f: '\f',
        n: '\n',
        r: '\r',
        t: '\t'
      },
      text,
      error = function (m) {
      //错误处理
        throw {
          name: 'SyntaxError',
          message: m,
          at: at,
          text: text
        };
      },
      next = function (c) {
        //检验c是否匹配当前字符
        if(c && c !== ch) {
          error("Expected '"+c+"' instead of'"+ ch+"'");
        }
        //获取下一个字符,当没有下一个字符时,返回空字符串
        ch = text.charAt(at);
        at +=1;
        return ch;
      },
      number = function() {
        //解析一个数字值
        let number,
          string = '';
        if(ch === '-') {
          string = '-';
          next('-');
        }
        while (ch >= '0' && ch <= '9') {
          string += ch;
          next();
        }
        if (ch === '.' ) {
          string += '.';
        }
        while (next() && ch >= '0' && ch <= '9') {
          string += ch;
        }
        if(ch === 'e' || ch === 'E') {
          string += ch;
          next();
          if (ch === '-' || ch === '+') {
            string += ch;
            next();
          }
          while (ch >= '0' && ch <= '9') {
            string += ch;
            next();
          }
        }
        number =+ string;
        if (isNaN(number)) {
          error("Bad number");
        }else {
          return number;
        }
      },
      string = function () {
        //解析一个字符串
        var hex,
          i,
          string = '',
          uffff;
        //当解析字符串值时,必须找到"和\字符
        if (ch==='"') {
          while (next()) {
            if (ch === '"') {
              next();
              return string;
            }else if (ch === '\\') {
              next();
              if (ch === 'u') {
                uffff = 0;
                for (i = 0; i < 4;i +=1) {
                  hex = parseInt(next(), 16);
                  if (!isFinite(hex)) {
                    break;
                  }
                  uffff = uffff * 16 +hex;
                }
                string += String.fromCharCode(uffff);
              }else if (typeof escapee[ch] === 'string') {
                string += escapee[ch];
              }else {
                break;
              }
            }else {
                string += ch;
            }
          }
        }
        error("Bad string");
      },
      white = function() {
        //跳过空白
        while (ch && ch <= ' ') {
          next();
        }
      },
      word = function() {
        //true,false或null
        switch (ch) {
          case 't':
            next('t');
            next('r');
            next('u');
            next('e');
            return true;
          case 'f':
            next('f');
            next('a');
            next('l');
            next('s');
            next('e');
            return false;
          case 'n':
            next('n');
            next('u');
            next('l');
            next('l');
            return null;
        }
        error("Unexpected'"+ch+"'");
      },
      array = function () {
        //解析一个数组值
        let array = [];
        if (ch === '[') {
          next('[');
          white();
        }
        if (ch === ']') {
          next(']');
          return array;//空数组
        }
        while (ch) {
          array.push(value());
          white();
          if (ch === ']') {
            next(']');
            return array;
          }
          next(',');
          white();
        }
        error("Bad array");
      },
      object = function () {
        //解析一个对象值
        let key,
          object = [];
        if (ch === '{') {
          next('{');
          white();
          if (ch === '}') {
            next('}');
            return object; //空对象
          }
          while (ch) {
            key = string();
            white();
            next(':');
            object[key] = value();
            white();
            if (ch === '}') {
              next('}');
              return object;
            }
            next(',');
            white();
          }
        }
        error("Bad object");
      },
      value = function () {
        //解析一个JSON值,它可以是对象、数组、字符串、数字或词
        white();
        switch (ch) {
          case '{':
            return object();
          case '[':
            return array();
          case '"':
            return string();
          case '-':
            return number();
          default:
            return ch >= '0' && ch<='9' ? number() : word();
        }
      };
      //返回JsonParse函数
      return function (source,reviver) {
        let result;
        text= source;
        at = 0;
        ch = ' ';
        result = value();
        white();
        if (ch) {
          error("Syntax error");
        }
        //如果存在reviver函数,则递归对这个新结构调用walk函数
        //开始时先创建一个临时启动对象,并以一个空字符串作为键名保存结果
        //如果没有reviver函数,就简单返回结果。
        return typeof reviver === 'function' ? 
          function walk(holder, key) {
            var k,v,val = holder[key];
            if(val && typeof val === 'object') {
              for(k in val) {
                if(Object.hasOwnProperty.call(val,k)) {
                  v = walk(val,k);
                  if(v !== undefined) {
                    val[k] = v;
                  }else {
                    delete val[k];
                  }
                }
              }
            }
            return reviver.call(holder,key,val);
          }({'': result},'') : result;
      }
  }();


相关文章
|
存储 前端开发 安全
前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
本文全面解析前端三种数据存储方式:Cookie、LocalStorage与SessionStorage。涵盖其定义、使用方法、生命周期、优缺点及典型应用场景,帮助开发者根据登录状态、用户偏好、会话控制等需求,选择合适的存储方案,提升Web应用的性能与安全性。(238字)
676 0
|
4月前
|
JSON 缓存 自然语言处理
多语言实时数据微店商品详情API:技术实现与JSON数据解析指南
通过以上技术实现与解析指南,开发者可高效构建支持多语言的实时商品详情系统,满足全球化电商场景需求。
|
6月前
|
存储 JSON 关系型数据库
【干货满满】解密 API 数据解析:从 JSON 到数据库存储的完整流程
本文详解电商API开发中JSON数据解析与数据库存储的全流程,涵盖数据提取、清洗、转换及优化策略,结合Python实战代码与主流数据库方案,助开发者构建高效、可靠的数据处理管道。
|
5月前
|
JSON 算法 API
淘宝商品评论API接口核心解析,json数据返回
淘宝商品评论API是淘宝开放平台提供的数据服务接口,允许开发者通过编程方式获取指定商品的用户评价数据,包括文字、图片、视频评论及评分等。其核心价值在于:
|
3月前
|
JSON Java Go
【GoGin】(2)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
bind或bindXXX函数(后文中我们统一都叫bind函数)的作用就是将,以方便后续业务逻辑的处理。
302 3
|
7月前
|
Web App开发 前端开发 JavaScript
前端性能优化利器:图片懒加载实战解析
前端性能优化利器:图片懒加载实战解析
|
3月前
|
XML JSON 数据处理
超越JSON:Python结构化数据处理模块全解析
本文深入解析Python中12个核心数据处理模块,涵盖csv、pandas、pickle、shelve、struct、configparser、xml、numpy、array、sqlite3和msgpack,覆盖表格处理、序列化、配置管理、科学计算等六大场景,结合真实案例与决策树,助你高效应对各类数据挑战。(238字)
245 0
|
7月前
|
JSON 定位技术 PHP
PHP技巧:解析JSON及提取数据
这就是在PHP世界里探索JSON数据的艺术。这场狩猎不仅仅是为了获得数据,而是一种透彻理解数据结构的行动,让数据在你的编码海洋中畅游。通过这次冒险,你已经掌握了打开数据宝箱的钥匙。紧握它,让你在编程世界中随心所欲地航行。
248 67
|
4月前
|
JSON 自然语言处理 API
多语言实时数据淘宝商品评论API:技术实现与JSON数据解析指南
淘宝商品评论多语言实时采集需结合官方API与后处理技术实现。建议优先通过地域站点适配获取本地化评论,辅以机器翻译完成多语言转换。在合规前提下,企业可构建多语言评论数据库,支撑全球化市场分析与产品优化。
|
6月前
|
人工智能 JSON 前端开发
如何解决后端Agent和前端UI之间的交互问题?——解析AG-UI协议的神奇作用
三桥君指出AG-UI协议通过SSE技术实现智能体与前端UI的标准化交互,解决流式传输、实时进度显示、数据同步等开发痛点。其核心功能包括结构化事件流、多Agent任务交接和用户中断处理,具有"一次开发到处兼容"、"UI灵活可扩展"等优势。智能体专家三桥君认为协议将AI应用从聊天工具升级为实用软件,适用于代码生成、多步骤工作流等场景,显著提升开发效率和用户体验。
1527 0

推荐镜像

更多
  • DNS