亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

簡(jiǎn)易版本JSON.stringify的實(shí)現(xiàn)及其六大特性詳解

 更新時(shí)間:2021年10月12日 09:11:28   作者:Nordon  
最近做項(xiàng)目發(fā)現(xiàn)JSON.stringify()使用場(chǎng)景真的挺多,我們都知道JSON.stringify()的作用是將JavaScript對(duì)象轉(zhuǎn)換為JSON字符串,下面這篇文章主要給大家介紹了JSON.stringify的實(shí)現(xiàn)及其六大特性的相關(guān)資料,需要的朋友可以參考下

前言

JSON.stringify是一個(gè)使用非常高頻的API,但是其卻存在一個(gè)特性,我們?cè)谑褂玫倪^程中需要留意這些特性以避免為代碼程序埋雷,那么接下來便一起動(dòng)手實(shí)現(xiàn)一個(gè)簡(jiǎn)易版本的jsonStringify函數(shù)

JSON.stringify六大特性

特性一

布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值

現(xiàn)在有這么一個(gè)對(duì)象:

const obj = {
    bol: new Boolean(true),
    num: new Number(1),
    str: new String(1)
}

利用typeof檢測(cè)obj各個(gè)屬性的數(shù)據(jù)類型

typeof obj.bol; // object
typeof obj.num; // object
typeof obj.str; // object

將其序列化stringify之后

JSON.stringify(obj); // {"bol":true,"num":1,"str":"1"}

此時(shí)再將其解析parse進(jìn)行各個(gè)屬性的數(shù)據(jù)類型

const stringifyObj = JSON.parse(JSON.stringify(obj));
typeof stringifyObj.bol; // boolean
typeof stringifyObj.num; // number
typeof stringifyObj.str; // string

特性二

NaN、Infinity、-Infinity以及null在序列化stringify時(shí)都會(huì)被當(dāng)作null

const obj = {
    nan: NaN,
    infinity: Infinity,
    null: null,
};

JSON.stringify(obj); // {"nan":null,"infinity":null,"null":null}

特性三

對(duì)象在序列化的時(shí)候,若是其存在toJSON函數(shù),這個(gè)函數(shù)返回的值就是整個(gè)對(duì)象序列化后的結(jié)果

const obj = {
    nan: NaN,
    infinity: Infinity,
    null: null,
    toJSON() {
        return "擁有toJSON函數(shù)";
    },
};

JSON.stringify(obj); // "擁有toJSON函數(shù)"

可以看到序列化之后的數(shù)據(jù)僅存在toJSON函數(shù)的返回值,其余數(shù)據(jù)全部忽略

⚠️:Date數(shù)據(jù)會(huì)被正常序列化,因?yàn)镈ate上部署了toJSON函數(shù),可以通過控制臺(tái)打印Date.prototype.toJSON得知

const obj = {
    date: new Date(),
};

JSON.stringify(obj); // {"date":"2021-10-08T11:43:31.881Z"}

特性四

表現(xiàn)不一的undefined、function和symbol

作為對(duì)象鍵值對(duì)時(shí):

作為值:

const obj = {
    undefined: undefined,
    fn() {},
    symbol: Symbol()
};

JSON.stringify(obj); // {}

作為鍵:

const fn = function () {};
const obj = {
    [undefined]: undefined,
    [fn]: function () {},
    [Symbol()]: Symbol()
};

JSON.stringify(obj); // {}

undefined、function和symbol作為對(duì)象的key和value時(shí),會(huì)在序列化時(shí)將其忽略

⚠️:此時(shí)可能會(huì)改變對(duì)象原有的順序,因?yàn)樯鲜鋈N數(shù)據(jù)會(huì)在序列化時(shí)被忽略

作為數(shù)組值時(shí):

const arr = [undefined, function fn() {}, Symbol()];

JSON.stringify(arr); // [null,null,null]

undefined、function和symbol作為數(shù)組的value時(shí),會(huì)在序列化時(shí)將其都轉(zhuǎn)換為null

單獨(dú)存在時(shí):

JSON.stringify(undefined); // undefined
JSON.stringify(function () {}); // undefined
JSON.stringify(Symbol()); // undefined

undefined、function和symbol單獨(dú)存在時(shí),會(huì)在序列化時(shí)都轉(zhuǎn)換為undefined

特性五

序列化過程中,僅會(huì)序列化可枚舉屬性,不可枚舉屬性將會(huì)忽視

const obj = {
    name: "nordon",
    age: 18,
};

// 將age修改為不可枚舉屬性
Object.defineProperty(obj, "age", {
    enumerable: false,
});

JSON.stringify(obj); // {"name":"nordon"}

⚠️:此舉也會(huì)改變對(duì)象的原有順序

特性六

循環(huán)引用的對(duì)象,會(huì)在序列化時(shí)拋出異常

const obj = {
    name: "nordon",
    age: 18,
};

const p = {
    name: 'wy',
    obj
}

obj.p = p

JSON.stringify(obj);

此時(shí)會(huì)導(dǎo)致控制臺(tái)拋出異常:

Uncaught TypeError: Converting circular structure to JSON     --> starting at object with constructor 'Object'     |     property 'p' -> object with constructor 'Object'     --- property 'obj' closes the circle     at JSON.stringify (<anonymous>)

手動(dòng)實(shí)現(xiàn)stringify

明白了JSON.stringify的一些特性,接下來便可以依據(jù)這些特性動(dòng)手實(shí)現(xiàn)一個(gè)kack版本

在動(dòng)手實(shí)現(xiàn)之前,先利用柯里化封裝一些數(shù)據(jù)類型校驗(yàn)的工具函數(shù):

const currying = (fn, ...outParams) => {
    // 獲取 fn 函數(shù)需要的參數(shù)個(gè)數(shù)
    const paramsLen = fn.length;

    return (...args) => {
        // 收集全部參數(shù)
        let params = [...outParams, ...args];
        // 若參數(shù)沒有達(dá)到 fn 需要的參數(shù),繼續(xù)收集參數(shù)
        if (params.length < paramsLen) {
            return currying(fn, ...params);
        }

        return fn(...params);
    };
};

/**
 * type: 類型 - [object Array]、[object Number]等
 * source: 數(shù)據(jù)源
 */
const judgeType = (type, source) => {
    return Object.prototype.toString.call(source) === type;
};

const isUndefined = currying(judgeType, "[object Undefined]");
const isSymbol = currying(judgeType, "[object Symbol]");
const isFunction = currying(judgeType, "[object Function]");
const isObject = currying(judgeType, "[object Object]");
const isNull = currying(judgeType, "[object Null]");

下面直接上代碼:

function jsonStringify(data) {
    let type = typeof data;

    if (isNull(data)) { 
// null 直接返回 字符串'null'
        return "null";
    } else if (data.toJSON && typeof data.toJSON === "function") {
// 配置了 toJSON函數(shù), 直接使用 toJSON 返回的數(shù)據(jù)且忽略其他數(shù)據(jù)
        return jsonStringify(data.toJSON());
    } else if (Array.isArray(data)) {
        let result = [];
        //如果是數(shù)組,那么數(shù)組里面的每一項(xiàng)類型又有可能是多樣的
        data.forEach((item, index) => {
            if (isUndefined(item) || isSymbol(item) || isFunction(item)) {
                result[index] = "null";
            } else {
                result[index] = jsonStringify(item);
            }
        });

        result = "[" + result + "]";

        return result.replace(/'/g, '"');
    } else if (isObject(data)) {
        // 處理普通對(duì)象
        let result = [];
        Object.keys(data).forEach((item, index) => {
            if (typeof item !== "symbol") {
                //key 如果是 symbol 對(duì)象,忽略
                if (
                    data[item] !== undefined &&
                    typeof data[item] !== "function" &&
                    typeof data[item] !== "symbol"
                ) {
                    //鍵值如果是 undefined、function、symbol 為屬性值,忽略
                    result.push(
                        '"' + item + '"' + ":" + jsonStringify(data[item])
                    );
                }
            }
        });

        return ("{" + result + "}").replace(/'/g, '"');
    } else if (type !== "object") {
        let result = data;

        //data 可能是基礎(chǔ)數(shù)據(jù)類型的情況在這里處理
        if (Number.isNaN(data) || data === Infinity) {
            //NaN 和 Infinity 序列化返回 "null"
            result = "null";
        } else if (isUndefined(data) || isSymbol(data) || isFunction(data)) {
            // 由于 function 序列化返回 undefined,因此和 undefined、symbol 一起處理
            return undefined;
        } else if (type === "string") {
            result = '"' + data + '"';
        }

        return String(result);
    }
}

至此簡(jiǎn)易版本的JSON.stringify完成,雖然能力尚欠缺許多,主要是提供一個(gè)思路,核心注釋已注釋在代碼中,可結(jié)合代碼和上文的特性一起理解

總結(jié)

到此這篇關(guān)于JSON.stringify實(shí)現(xiàn)及其六大特性詳解的文章就介紹到這了,更多相關(guān)簡(jiǎn)易版本JSON.stringify及特性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容

    javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容

    這篇文章主要介紹了javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容,需要的朋友可以參考下
    2014-12-12
  • JS幻想 讀取二進(jìn)制文件

    JS幻想 讀取二進(jìn)制文件

    如果說讓JavaScript讀取站點(diǎn)上一文本文件,那不過是個(gè)再簡(jiǎn)單不了的事了;但若說要換成一個(gè)二進(jìn)制的文件,并且是完全靜態(tài)的讀取,那似乎有點(diǎn)天方夜譚了。
    2009-04-04
  • js生成隨機(jī)數(shù)方法和實(shí)例

    js生成隨機(jī)數(shù)方法和實(shí)例

    這篇文章主要介紹了js生成隨機(jī)數(shù)方法和實(shí)例,由js生成一切隨機(jī)數(shù)的基礎(chǔ)都是Math.random(),有興趣的可以了解一下。
    2017-01-01
  • 微信小程序?qū)崿F(xiàn)圖片翻轉(zhuǎn)效果的實(shí)例代碼

    微信小程序?qū)崿F(xiàn)圖片翻轉(zhuǎn)效果的實(shí)例代碼

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)圖片翻轉(zhuǎn)效果的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • BootStrap表單控件之復(fù)選框checkbox和單選擇按鈕radio

    BootStrap表單控件之復(fù)選框checkbox和單選擇按鈕radio

    這篇文章主要介紹了BootStrap表單控件之復(fù)選框checkbox和單選擇按鈕radio的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • bootstrap警告框使用方法解析

    bootstrap警告框使用方法解析

    這篇文章主要為大家詳細(xì)介紹了bootstrap警告框使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 利用canvas實(shí)現(xiàn)的加載動(dòng)畫效果實(shí)例代碼

    利用canvas實(shí)現(xiàn)的加載動(dòng)畫效果實(shí)例代碼

    之前看到一個(gè)Android的加載效果不錯(cuò),一直想自己動(dòng)手做一個(gè),正好這段時(shí)間重溫了一個(gè)Canvas,所以就嘗試了一下。下面這篇文章主要給大家介紹了關(guān)于利用canvas實(shí)現(xiàn)加載效果的相關(guān)資料,需要的朋友可以參考下。
    2017-07-07
  • uniapp中使用?uni.navigateBack()?返回上級(jí)頁面并傳參的方法

    uniapp中使用?uni.navigateBack()?返回上級(jí)頁面并傳參的方法

    最近遇到這樣的需求在A頁面中通過跳轉(zhuǎn)到B頁面,在B頁面中處理的數(shù)據(jù),需要跳轉(zhuǎn)回A頁面供其使用,本文給大家分享uniapp中使用?uni.navigateBack()?返回上級(jí)頁面并傳參的操作方法,感興趣的朋友一起看看吧
    2023-10-10
  • JavaScript刪除數(shù)組元素的方法

    JavaScript刪除數(shù)組元素的方法

    這篇文章主要介紹了JavaScript刪除數(shù)組元素的方法,實(shí)例分析了javascript中delete函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • JavaScript隱式類型轉(zhuǎn)換

    JavaScript隱式類型轉(zhuǎn)換

    JavaScript的數(shù)據(jù)類型是非常弱的(不然不會(huì)叫它做弱類型語言了)!在使用算術(shù)運(yùn)算符時(shí),運(yùn)算符兩邊的數(shù)據(jù)類型可以是任意的,比如,一個(gè)字符串可以和數(shù)字相加
    2016-03-03

最新評(píng)論