如何实现一个JSON.parse

之前收藏的一个把 json字符串转对象的解析器,代码比较易懂,直接贴源码。对于刚接触这块的同学应该能起到入门的作用
var json = {}

json.parse = function(text) {
    var at = 0
    var ch = ' '

    var escapee = {
        '"': '"',
        '\\': '\\',
        '/': '/',
        b: '\b',
        f: '\f',
        n: '\n',
        r: '\r',
        t: '\t'
    }

    var error = function(m) {
        console.log(m);
        throw {
            name: 'SyntaxError',
            message: m,
            at: at,
            text: text
        }
    }

    var next = function(c) {
        if (c && c !== ch) {
            error("Expected '" + c + "' instead of '" + ch + "'")
        }
        ch = text.charAt(at)
        at = at + 1

        return ch
    }

    var white = function() {
        while (ch && ch <= ' ') {
            next()
        }
    }

    var number = function() {
        var number
        var 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 - 0
        if (!isFinite(number)) {
            error('Bad number')
        } else {
            return number
        }
    }

    var string = function() {
        var hex
        var i
        var string = ''
        var uffff

        if (ch === '"') {
            while (next()) {
                if (ch === '"') {
                    next()
                    return string // 空字符串
                }

                if (ch === '\\') {
                    next()
                    if (ch === 'u') {
                        uffff = 0
                        for (var 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')
    }

    var word = function() {
        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 + "'");
    }
    var value

    var array = function() {
        var 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')
    }

    var object = function() {
        var key
        var object = {}
        if (ch === '{') {
            next('{')
            white()

            if (ch === '}') {
                next('}')
                return object // 空对象
            }

            while (ch) {
                key = string()
                white()
                next(':')

                if (Object.hasOwnProperty.call(object, key)) {
                    error('Duplicate key "' + key + '"');
                }

                object[key] = value()
                white()
                if (ch === '}') {
                    next('}')
                    return object
                }
                next(',')
                white()
            }
        }

        error('Bad object')
    }

    value = function() {
        white()
        switch (ch) {
            case '{':
                return object()
            case '[':
                return array()
            case '"':
                return string()
            case '-':
                return number()
            default:
                return ch >= '0' && ch <= '9' ? number() : word()
        }
    }

    return value(text)
}

实现思路

json的结构分析
json的结构包含几种元素:
object(name value pair object)
此处指狭义的对象,名值对形式。广义上任何元素都是对象。
array
由[]符号包裹,元素用英文逗号分隔。
字面类型
字面类型最为简单,不能再嵌套
number
boolean
true or false
null

下面放几张json.org的图,以直观的形式展示json格式。

clipboard.png

clipboard.png

clipboard.png

object 内部的value和array内部的元素都可以是任意组成类型,可以存在任意层次的嵌套。因此用递归方式解析比较简单。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSON.parse(JSON.stringify(obj))是一种将JavaScript对象转换为JSON字符串再转回JavaScript对象的常见方法。在这个过程中,JSON.stringify()方法将JavaScript对象转换为JSON字符串,而JSON.parse()方法则将JSON字符串转换回JavaScript对象。 这种方法的主要用途是在JavaScript中对对象进行深拷贝。通过先将对象转换为JSON字符串,然后再将其转换回对象,可以创建一个原始对象的副本,而不是只是引用原始对象。 例如,假设我们有一个包含复杂嵌套结构的JavaScript对象obj,我们想要创建它的副本。我们可以使用JSON.parse(JSON.stringify(obj))来实现这一目标。 这种方法的好处是它可以处理几乎所有类型的JavaScript对象,包括数组、函数和日期对象等。 但需要注意的是,JSON.stringify()方法会忽略对象的某些属性,例如函数和原型链上的属性。因此,通过JSON.parse(JSON.stringify(obj))进行深拷贝时,可能会丢失一些对象的特定行为。 此外,在使用JSON.parse()和JSON.stringify()方法时,需要确保处理的对象是有效的JSON格式。如果对象中包含不支持的数据类型或循环引用,这些方法可能会导致错误。 总结起来,JSON.parse(JSON.stringify(obj))是一种将JavaScript对象转换为JSON字符串再转回JavaScript对象的方法,用于实现对象的深拷贝。但需要注意处理的对象应为有效的JSON格式,并且一些特定类型的属性可能会丢失。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [了解 JSON.parse() 和 JSON.stringify()](https://blog.csdn.net/allway2/article/details/123856863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法](https://download.csdn.net/download/weixin_38743391/13002642)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值