Zyyo

Just for fun

文章

24

标签

25

评论

4049

数据统计

成立

355天

文章

24篇

评论

4049条

标签

25个

最近文章

使用javscript手写json-parse

空虚使我寂寞难耐索性开整
一个非常简单的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)
}

使用javscript手写json-parse

发布于

April 2, 2025

分类

实用分享

版权协议

MIT

评论
😀
已有 12 条评论

    Нужен эвакуатор? эвакуатор спб стоимость быстрый выезд по Санкт-Петербургу и области. Аккуратно погрузим легковое авто, кроссовер, мотоцикл. Перевозка после ДТП и поломок, помощь с запуском/колесом. Прозрачная цена, без навязываний.

    Нужны заклепки? заклепки вытяжные нержавеющие купить для прочного соединения листового металла и профиля. Стойкость к коррозии, аккуратная головка, надежная фиксация даже при вибрациях. Подбор размеров и типа борта, быстрая отгрузка и доставка.

    1xbet-apk-270 2025-12-19 回复

    Le site web telecharger 1xbet pour android propose des informations sur les paris sportifs, les cotes et les evenements en direct. Football, tournois populaires, cotes et statistiques y sont presentes. Ce site est ideal pour se familiariser avec les fonctionnalites de la plateforme.

    1xbet-405 2025-12-19 回复

    Envie de parier 1xbet apk est une plateforme de paris sportifs en ligne pour la Republique democratique du Congo. Football et autres sports, paris en direct et d'avant-match, cotes, resultats et statistiques. Presentation des fonctionnalites du service.

    [...]好友动态说说:#1763297693喵喵小站・博客志 · 绯色之喵 · 2 天前足球城的名字永不可替代,北方明珠着传承蓝色的血脉,胜利的歌声响彻云霄外,呐喊跳跃在这里创造新时代!{cat_webmusic id="2735958683"}遗失的记忆——大连森林动物园喵喵小站・博客志 · 绯色之喵 · 2 天前上次来动物园还是十多年前学校郊游,因为机会难得可以免费入园,所以今天就[...]

    半截の诗 2025-11-19 回复

    [...]说说:#1763297693喵喵小站・博客志 · 绯色之喵 · 2 天前足球城的名字永不可替代,北方明珠着传承蓝色的血脉,胜利的歌声响彻云霄外,呐喊跳跃在这里创造新时代!{cat_webmusic id="2735958683"}遗失的记忆——大连森林动物园喵喵小站・博客志 · 绯色之喵 · 2 天前上次来动物园还是十多年前学校郊游,因为机会难得可以免费入园,所以今天就又来动物[...]

    崔话记 2025-05-26 回复

    在JS已经自动JSON API的情况下,这个解析器是为了用于老的IE浏览器吗?

      作者 Zyyo 2025-08-14 回复
      @崔话记

      主要是闲的,看看能不能实现

        boyarka 2025-11-18 回复
        @Zyyo

        You coulod definitely see yoir enthusiasm iin the artice you write.
        Thee world hopes for even more passionate writers such as
        you who aren't afraid to say how they believe. Always go
        after your heart.

    cqpc 2025-05-10 回复

    1

感谢支持!

微信二维码

请使用微信扫描二维码打赏。

支付宝二维码

请使用支付宝扫描二维码打赏。