惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
H
Help Net Security
V
Visual Studio Blog
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
MyScale Blog
MyScale Blog
The Cloudflare Blog
Martin Fowler
Martin Fowler
D
Docker
腾讯CDC
F
Fortinet All Blogs
雷峰网
雷峰网
GbyAI
GbyAI
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
博客园 - 叶小钗

Zyyo

Kimi K3 模型深度评测:智能体编程与知识工作的新标杆 - Zyyo 🎉 ZYyo Agent WebUI 诞生了! 我对AI的思考 - Zyyo Pi Agent Core:极简 AI Coding Agent 核心解析 锐捷校园网认证工具 - Zyyo 一个综合树维教务系统的选课排课客户端基于nodejs - Zyyo Archlinux保姆级安装教程 - Zyyo 闲来无事-Vue3实现贪吃蛇小游戏 - Zyyo Zyang一款从0打造的优雅Typecho主题 - Zyyo 全新开源个人主页-ZYYO主页 - Zyyo 第一辆自行车-喜德盛ad300拿下 - Zyyo 临近期末的近况 - Zyyo 新跑表-华为GT Runner - Zyyo
使用javscript手写json-parse - Zyyo
Zyyo · 2025-04-02 · via Zyyo

数据统计

使用javscript手写json-parse

Zyyo 2025-04-02 270

⚠️本文发布于 438 天前,内容可能已过时,请注意甄别信息的准确性。

空虚使我寂寞难耐索性开整
一个非常简单的JsonParse
花了我一下午加一晚上的心思
目前已经支持对象,数组互相嵌套,数字,字符串 布尔

还未实现

严格的错误校验,本项目是根据一个标准的Json格式来实现的,没有进行格式判断,你如果拿出来一个未经严格校验的json字符串来解析,甚至有可能得到正确的结果
不支持更多数字类型
不支持特殊字符转义
不支持顶层数组(我写完才发现有这个特性)。。。

作者zyyo
项目地址
https://github.com/ZYYO666/fuckDemo
(这个项目专门放各种demo)




function Json(string, _index = 0) {
    let index = _index
    let json = string.trim()
    let jsonparse = json.split('')
    let prevAttr = ''
    let isArray = false
    let isFirst = true
    const result = {}



    //通用的处理,调用其他处理器
    function parse() {
        skip()
        if (jsonparse[index] == '{') {
            return parseDakuohao1()
        } else if (jsonparse[index] == ':') {
            return parseMaohao()
        } else if (jsonparse[index] == '"') {
            return parseString()
        } else if (jsonparse[index] == ',') {
            return parseDouhao()
        } else if (/\d/.test(jsonparse[index]) || jsonparse[index] == '-') {
            return parseNum()
        } else if (json.slice(index, index + 4) === 'true') {
            return parseTrue()
        } else if (json.slice(index, index + 5) === 'false') {
            return parseFalse()
        } else if (json.slice(index, index + 4) === 'null') {
            return parseNull()
        } else if (jsonparse[index] == '}') {
            return parseDakuohao2()
        } else if (jsonparse[index] == '[') {
            return parseArray1()
        } else if (jsonparse[index] == ']') {
            return parseArray2()
        } else if (index == jsonparse.length) {
            throw new Error('标签未闭合')
        } else {
            console.log(result);
            throw new Error('未知字符' + jsonparse[index])
        }
    }
    function skip() {
        while (jsonparse[index] == ' ' || jsonparse[index] == '\n') {
            index++
        }
    }
    function parseMaohao() {
        index++
        return parse()
    }
    function parseArray1() {
        index++
        if (prevAttr == '') {
            throw new Error('[]不能用作属性')
        }
        result[prevAttr] = []
        isArray = true
        return parse()
    }
    function parseArray2() {
        index++
        prevAttr = ''
        isArray = false
        return parse()
    }
    function parseTrue() {
        index += 4
        if (prevAttr == '') {
            throw new Error('True不能用作属性')
        }
        if (isArray) {
            result[prevAttr].push(true)
        } else {
            result[prevAttr] = true
            prevAttr = ''
        }
        return parse()
    }
    function parseFalse() {
        index += 5
        if (prevAttr == '') {
            throw new Error('False不能用作属性')
        }
        if (isArray) {
            result[prevAttr].push(false)
        } else {
            result[prevAttr] = false
            prevAttr = ''
        }
        return parse()
    }
    function parseNull() {
        index += 4
        if (prevAttr == '') {
            throw new Error('null不能用作属性')
        }
        if (isArray) {
            result[prevAttr].push(null)
        } else {
            result[prevAttr] = null
            prevAttr = ''
        }
        return parse()
    }
    function parseNum() {

        let num = ''
        while (jsonparse[index] !== '}' && jsonparse[index] !== ',' && jsonparse[index] !== ']') {
            num += jsonparse[index]
            index++
        }
        if (typeof num !== 'number' && isNaN(num)) {
            throw new Error('数字格式错误')
        }
        if (prevAttr == '') {
            throw new Error('json格式错误')
        }
        num = Number(num)
        if (isArray) {
            result[prevAttr].push(num)
        } else {
            result[prevAttr] = num
            prevAttr = ''
        }
        return parse()

    }

    function parseDakuohao1() {
        if (isFirst == true) {
            index++
            isFirst = false

        } else {
            const res = Json(json, index)
            index = res.index

            if (prevAttr == '') {
                throw new Error('错误')
            }
            if (isArray) {
                result[prevAttr].push(res.object)
            } else {
                result[prevAttr] = res.object
                prevAttr = ''
            }
        }
        return parse()
    }
    function parseDakuohao2() {
        return {
            object: result,
            index: ++index
        }
    }
    function parseDouhao() {
        index++
        return parse()
    }
    function parseString() {
        let str = ''
        index++ //第一个双引号
        while (jsonparse[index] !== '"') {
            str += jsonparse[index]
            index++
        }
        index++ //第二个双引号

        if (prevAttr == '') {
            prevAttr = str
            result[str] = undefined;
            return parse()
        }

        if (isArray) {
            result[prevAttr].push(str)
        } else {
            result[prevAttr] = str

            prevAttr = ''
        }
        return parse()
    }
    return parse()


}

const json1 = {
    id: [1, {
        a: 1,
        b: {
            a: 1,
            b: 2
        }

    }, "zyyo", 3, 4, 5],
    name: "Example Object",
    isActive: true,
    details: {
        description: "This is a complex object for testing purposes.",
        metadata: {
            version: -2.5,
            createdBy: "admin",
            isVerified: false,
            history: {
                firstCreated: "2023-01-01",
                lastUpdated: "2023-10-01",
                updates: {
                    total: 5,
                    recent: {
                        date: "2023-09-15",
                        changes: {
                            added: 3,
                            removed: 1,
                            modified: 2
                        }
                    }
                }
            }
        }
    },
    settings: {
        preferences: {
            theme: "dark",
            notifications: {
                email: true,
                sms: false,
                push: true
            }
        },
        limits: {
            maxConnections: 10,
            timeout: 30000
        }
    },
    tags: {
        category: "test",
        priority: "high",
        attributes: {
            security: "confidential",
            scope: "internal"
        }
    }
};

const testjson = JSON.stringify(json1);



try {
    console.time("json")
    for (let i = 0; i < 10000; i++) {
       Json(testjson).object;
    }
    console.timeEnd("json")
    console.time("jsonpaser")
    for (let i = 0; i < 10000; i++) {
         JSON.parse(testjson)
    }
    console.timeEnd("jsonpaser")
} catch (error) {
    console.log(error.message)
}