JSON.stringify() 的深入理解

序言

最近在看《你所不知道的javascript》[中卷]一書(shū)涎显,第一部分是類型和語(yǔ)法暗膜。本文是基于這部分的產(chǎn)物彰导。在強(qiáng)制類型轉(zhuǎn)換->抽象值操作-> toString 部分藏否,其中對(duì)工具函數(shù) JSON.stringify(..) 將 JSON 對(duì)象序列化為字符串部分介紹進(jìn)行了詳細(xì)的介紹瓶殃,而自己之前對(duì) JSON.stringify(..) 認(rèn)識(shí)也比較淺。

JSON.stringify() 不論是在面試還是工作中(對(duì)象的深拷貝副签、json 字符串序列化)都是重點(diǎn)遥椿,總是能看到它的身影。所以針對(duì)這個(gè)知識(shí)點(diǎn)記錄整理一下淆储。

語(yǔ)法

參考MDN

JSON.stringify(value[, replacer [, space]])

參數(shù)

  • value

將要序列化成 一個(gè)JSON 字符串的值冠场。

這是第一個(gè)參數(shù),應(yīng)該都不陌生本砰,最常用的也是這個(gè)碴裙。其他兩個(gè)基本用不到。

一般傳入一個(gè)對(duì)象灌具。但是不僅僅如此青团,還可以傳入其他值哦。

  • replacer | 可選

可以三種類型的值:

  1. 函數(shù)咖楣,在序列化過(guò)程中督笆,被序列化的值的每個(gè)屬性都會(huì)經(jīng)過(guò)該函數(shù)的轉(zhuǎn)換和處理
  2. 數(shù)組,只有包含在這個(gè)數(shù)組中的屬性名才會(huì)被序列化到最終的 JSON 字符串中
  3. null或者未提供诱贿,對(duì)象所有的屬性都會(huì)被序列化

一般情況下娃肿,我們都不傳,按第3種方式處理珠十。

  • space | 可選

指定縮進(jìn)用的空白字符串料扰,用于美化輸出。

可以指定三種類型的值:

  1. 數(shù)字焙蹭,代表有多少的空格晒杈。上限為10,該值若小于1孔厉,則意味著沒(méi)有空格拯钻。
  2. 字符串帖努,字符串的前十個(gè)字母,該字符串將被作為空格粪般。
  3. null或者未提供拼余,將沒(méi)有空格。

一般情況下亩歹,我們都不傳匙监,按第3種方式處理。

返回值

一個(gè)表示給定值的 json 字符串小作。

深入理解

ToString 規(guī)則

JSON 字符串化并非嚴(yán)格意義上的強(qiáng)制類型轉(zhuǎn)換亭姥,但其中涉及 ToString 的相關(guān)規(guī)則:

  1. 基本類型值的字符串化規(guī)則為:null 轉(zhuǎn)換為 "null",undefined 轉(zhuǎn)換為 "undefined"顾稀,true 轉(zhuǎn)換為 "true"致份。
  2. 數(shù)字的字符串化則遵循通用規(guī)則,變成字符串?dāng)?shù)字础拨,其中對(duì)極小和極大的數(shù)字使用指數(shù)形式:
// 1.07 連續(xù)乘以七個(gè) 1000
var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
// 七個(gè)1000一共21位數(shù)字
a.toString(); // "1.07e21"
  1. 對(duì)普通對(duì)象來(lái)說(shuō),除非自行定義绍载,否則 toString()(Object.prototype.toString())返回
    內(nèi)部屬性 [[Class]] 的值诡宗,如 "[object Object]"。

如果對(duì)象有自己的 toString() 方法击儡,字符串化時(shí)就會(huì)調(diào)用該方法并使用其返回值塔沃。

將對(duì)象強(qiáng)制類型轉(zhuǎn)換為 string 是通過(guò) ToPrimitive 抽象操作來(lái)完成的。

補(bǔ)充:

[[Class]]:所有 typeof 返回值為 "object" 的對(duì)象(如數(shù)組)都包含一個(gè)內(nèi)部屬性 [[Class]](可以把它看作一個(gè)內(nèi)部的分類阳谍,而非傳統(tǒng)的面向?qū)ο笠饬x上的類)蛀柴。這個(gè)屬性無(wú)法直接訪問(wèn),一般通過(guò) Object.prototype.toString(..) 來(lái)查看矫夯。

Object.prototype.toString.call( [1,2,3] );
// "[object Array]"
Object.prototype.toString.call( /regex-literal/i );
// "[object RegExp]"
上例中鸽疾,數(shù)組的內(nèi)部 [[Cl

ToPrimitive:為了將值轉(zhuǎn)換為相應(yīng)的基本類型值,抽象操作 ToPrimitive 會(huì)首先
(通過(guò)內(nèi)部操作 DefaultValue)檢查該值是否有 valueOf() 方法训貌。
如果有并且返回基本類型值制肮,就使用該值進(jìn)行強(qiáng)制類型轉(zhuǎn)換。如果沒(méi)有就使用 toString()
的返回值(如果存在)來(lái)進(jìn)行強(qiáng)制類型轉(zhuǎn)換递沪。
如果 valueOf() 和 toString() 均不返回基本類型值豺鼻,會(huì)產(chǎn)生 TypeError 錯(cuò)誤。

對(duì)大多數(shù)簡(jiǎn)單值來(lái)說(shuō)款慨,JSON 字符串化和 toString() 的效果基本相同儒飒,只不過(guò)序列化的結(jié)
果總是字符串:

JSON.stringify( 42 ); // "42"
JSON.stringify( "42" ); // ""42"" (含有雙引號(hào)的字符串)
JSON.stringify( null ); // "null"
JSON.stringify( true ); // "true"

json 序列化為字符串時(shí),需要注意的點(diǎn):

  • 轉(zhuǎn)換值如果有toJSON()方法檩奠,該方法定義什么值將被序列化桩了。
  • 非數(shù)組對(duì)象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中附帽。
  • 布爾值、數(shù)字圣猎、字符串的包裝對(duì)象在序列化過(guò)程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值士葫。
  • undefined、任意的函數(shù)以及 symbol 值送悔,在序列化過(guò)程中
    • 出現(xiàn)在非數(shù)組對(duì)象的屬性值中時(shí)慢显,會(huì)被忽略(包括屬性名)
    • 出現(xiàn)在數(shù)組中時(shí),會(huì)被轉(zhuǎn)換成 null(以保證單元位置不變)欠啤。
    • 函數(shù)荚藻、undefined被單獨(dú)轉(zhuǎn)換時(shí),會(huì)返回undefined洁段,如 JSON.stringify(function(){}) or JSON.stringify(undefined).
  • 對(duì)包含循環(huán)引用的對(duì)象(對(duì)象之間相互引用应狱,形成無(wú)限循環(huán))執(zhí)行此方法,會(huì)拋出錯(cuò)誤祠丝。
  • 所有以 symbol 為屬性鍵的屬性都會(huì)被完全忽略掉疾呻,即便 replacer 參數(shù)中強(qiáng)制指定包含了它們。
  • Date日期調(diào)用了toJSON()將其轉(zhuǎn)換為了string字符串(同Date.toISOString())写半,因此會(huì)被當(dāng)做字符串處理岸蜗。
  • NaN和Infinity格式的數(shù)值及null都會(huì)被當(dāng)做null。
  • 其他類型的對(duì)象叠蝇,包括Map/Set/weakMap/weakSet璃岳,僅會(huì)序列化可枚舉的屬性。
  • 會(huì)拋棄對(duì)象的 constructor悔捶。即 JSON.parse(JSON.stringify(obj))后得到的對(duì)象铃慷,不管這個(gè)對(duì)象原來(lái)的構(gòu)造函數(shù)是什么,在深拷貝之后都會(huì)變成 Object蜕该。
JSON.stringify({});                        // '{}'
JSON.stringify(true);                      // 'true'
JSON.stringify("foo");                     // '"foo"'
JSON.stringify([1, "false", false]);       // '[1,"false",false]'
JSON.stringify({ x: 5 });                  // '{"x":5}'

JSON.stringify({x: 5, y: 6});              
// "{"x":5,"y":6}"

JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); 
// '[1,"false",false]'

JSON.stringify({x: undefined, y: Object, z: Symbol("")}); 
// '{}'

JSON.stringify([undefined, Object, Symbol("")]);          
// '[null,null,null]' 

JSON.stringify({[Symbol("foo")]: "foo"});                 
// '{}'

JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]);
// '{}'

JSON.stringify(
    {[Symbol.for("foo")]: "foo"}, 
    function (k, v) {
        if (typeof k === "symbol"){
            return "a symbol";
        }
    }
);

// undefined 

// 不可枚舉的屬性默認(rèn)會(huì)被忽略:
JSON.stringify( 
    Object.create(
        null, 
        { 
            x: { value: 'x', enumerable: false }, 
            y: { value: 'y', enumerable: true } 
        }
    )
);

// "{"y":"y"}"

// 序列化犁柜,然后反序列化后丟失 constructor
function Animation (name) { this.name = name; }
var dog = new Animation('小白');
console.log(dog.constructor); // ? Animation (name) { this.name = name; }

var obj = JSON.parse(JSON.stringify(dog));
console.log(obj.constructor); // ? Object() { [native code] }

安全的 json 值

所有安全的 JSON 值都可以使用 JSON.stringify(..) 字符串化。安全的
JSON 值是指能夠呈現(xiàn)為有效 JSON 格式的值堂淡。

不安全的 JSON 值:undefined赁温、function、symbol(ES6+)和包含循環(huán)引用的對(duì)象都不符合 JSON 結(jié)構(gòu)標(biāo)準(zhǔn)淤齐,支持 JSON 的語(yǔ)言無(wú)法處理它們股囊。例如:

JSON.stringify( undefined ); // undefined
JSON.stringify( function(){} ); // undefined
JSON.stringify(
 [1,undefined,function(){},4]
); // "[1,null,null,4]"
JSON.stringify(
 { a:2, b:function(){} }
); // "{"a":2}"

將不安全的 json 轉(zhuǎn)換成安全的 json

  • 方式1:toJSON

如果對(duì)象中定義了 toJSON() 方法,JSON 字符串化時(shí)會(huì)首先調(diào)用該方法更啄,然后用它的返回值來(lái)進(jìn)行序列化稚疹。

如果要對(duì)含有非法 JSON 值的對(duì)象做字符串化,或者對(duì)象中的某些值無(wú)法被序列化時(shí),就需要定義 toJSON() 方法來(lái)返回一個(gè)安全的 JSON 值内狗。例如:

var o = { };
var a = {
 b: 42,
 c: o,
 d: function(){}
};

// 在a中創(chuàng)建一個(gè)循環(huán)引用
o.e = a;
// 循環(huán)引用在這里會(huì)產(chǎn)生錯(cuò)誤
// JSON.stringify( a );

// 自定義的JSON序列化
a.toJSON = function() {
 // 序列化僅包含b
 return { b: this.b };
};
JSON.stringify( a ); // "{"b":42}"

toJSON() 應(yīng)該“返回一個(gè)能夠被字符串化的安全的 JSON 值”怪嫌,而不是“返回一個(gè) JSON 字符串”。

  • 方式2:向 JSON.stringify(..) 傳遞一個(gè)可選參數(shù) replacer

可選參數(shù) replacer柳沙,可以是數(shù)組或者函數(shù)岩灭,用來(lái)指定對(duì)象序列化過(guò)程中哪些屬性應(yīng)該被處理,哪些應(yīng)該被排除赂鲤,和 toJSON() 很像噪径。

如果 replacer 是一個(gè)數(shù)組,那么它必須是一個(gè)字符串?dāng)?shù)組数初,其中包含序列化要處理的對(duì)象的屬性名稱找爱,除此之外其他的屬性則被忽略。

作為函數(shù)泡孩,它有兩個(gè)參數(shù)车摄,鍵(key)值(value)都會(huì)被序列化。

  • 如果返回一個(gè) Number, 轉(zhuǎn)換成相應(yīng)的字符串被添加入JSON字符串仑鸥。
  • 如果返回一個(gè) String, 該字符串作為屬性值被添加入JSON吮播。
  • 如果返回一個(gè) Boolean, "true" 或者 "false"被作為屬性值被添加入JSON字符串。
  • 如果返回任何其他對(duì)象眼俊,該對(duì)象遞歸地序列化成JSON字符串薄料,對(duì)每個(gè)屬性調(diào)用replacer方法。除非該對(duì)象是一個(gè)函數(shù)泵琳,這種情況將不會(huì)被序列化成JSON字符串。
  • 如果返回undefined誊役,該屬性值不會(huì)在JSON字符串中輸出获列。

注意: 不能用replacer方法,從數(shù)組中移除值(values)蛔垢,如若返回undefined或者一個(gè)函數(shù)击孩,將會(huì)被null取代。

所以如果要忽略某個(gè)鍵就返回 undefined鹏漆,否則返回指定的值巩梢。舉例:

var a = {
 b: 42,
 c: "42",
 d: [1,2,3]
};
JSON.stringify( a, ["b","c"] ); // "{"b":42,"c":"42"}"
JSON.stringify( a, function(k,v){
 if (k !== "c") return v;
} ); // "{"b":42,"d":[1,2,3]}"
var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};


function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
}
// 函數(shù)
var jsonString = JSON.stringify(foo, replacer); // {"week":45,"month":7}

// 數(shù)組
JSON.stringify(foo, ['week', 'month']);  
// '{"week":45,"month":7}', 只保留“week”和“month”屬性值。

JSON-js 是老外寫(xiě)的一個(gè)對(duì)JSON處理的小工具饭聚,其中的decycle和retrocycle是專門(mén)用來(lái)破除/恢復(fù)這種循環(huán)結(jié)構(gòu)的忌警。基本用法如下:

let a={name:'aaa',link:''}
let b={name:'bbb',link:''}
a.link=b;
b.link=a;
/*decycle*/
JSON.stringify(JSON.decycle(a));
/*結(jié)果*/
"{"name":"aaa","link":{"name":"bbb","link":{"$ref":"$"}}}"

可以看到秒梳,破解循環(huán)后確實(shí)沒(méi)有報(bào)錯(cuò)法绵,但是出現(xiàn)了ref:''這樣的代碼箕速,這種標(biāo)志表示識(shí)別除了循環(huán)引用,其中ref為固定的朋譬,右邊的'...'表示它循環(huán)引用的部分盐茎,單個(gè)$為頂層對(duì)象。

美化序列化后的字符串

JSON.string 還有一個(gè)可選參數(shù) space徙赢,用來(lái)指定輸出的縮進(jìn)格式字柠。

  • 正整數(shù)時(shí),是指定每一級(jí)縮進(jìn)的字符數(shù),最多10個(gè)空格
  • 字符串時(shí)犀忱,是最前面的十個(gè)字符被用于每一級(jí)的縮進(jìn):
var a = {
    b: 42,
    c: "42",
    d: [1,2,3]
};

// 數(shù)字
JSON.stringify( a, null, 3 );
/*
"{
   "b": 42,
   "c": "42",
   "d": [
      1,
      2,
      3
   ]
}"
*/

// 字符串
JSON.stringify( a, null, "-----" );
/*
"{
-----"b": 42,
-----"c": "42",
-----"d": [
----------1,
----------2,
----------3
-----]
}"
*/

反序列化:JSON.parse(..)

參考MDN

語(yǔ)法:

JSON.parse(text[, reviver])

參數(shù):

  • text:要被解析成JavaScript值的字符串募谎。
  • reviver(可選):轉(zhuǎn)換器, 如果傳入該參數(shù)(函數(shù)),可以用來(lái)修改解析生成的原始值阴汇,調(diào)用時(shí)機(jī)在parse函數(shù)返回之前数冬。

返回值:Object類型, 對(duì)應(yīng)給定JSON文本的對(duì)象/值

reviver 參數(shù)和 JSON.stringify 的第二個(gè)參數(shù) replacer,原理差不多搀庶。具體為:

  • 解析值本身以及它所包含的所有屬性拐纱,會(huì)按照一定的順序(從最最里層的屬性開(kāi)始,一級(jí)級(jí)往外哥倔,最終到達(dá)頂層秸架,也就是解析值本身)分別的去調(diào)用 reviver 函數(shù),在調(diào)用過(guò)程中咆蒿,當(dāng)前屬性所屬的對(duì)象會(huì)作為 this 值东抹,當(dāng)前屬性名和屬性值會(huì)分別作為第一個(gè)和第二個(gè)參數(shù)傳入 reviver 中。
  • 如果 reviver 返回 undefined沃测,則當(dāng)前屬性會(huì)從所屬對(duì)象中刪除缭黔,如果返回了其他值,則返回的值會(huì)成為當(dāng)前屬性新的屬性值蒂破。
  • 當(dāng)遍歷到最頂層的值時(shí)馏谨,傳入 reviver 函數(shù)的參數(shù)會(huì)是空字符串 ""(因?yàn)榇藭r(shí)已經(jīng)沒(méi)有真正的屬性)和當(dāng)前的解析值(有可能已經(jīng)被修改過(guò)了),當(dāng)前的 this 值會(huì)是 {"": 修改過(guò)的解析值}附迷,在編寫(xiě) reviver 函數(shù)時(shí)惧互,要注意到這個(gè)特例。
  • 函數(shù)的遍歷順序依照:從最內(nèi)層開(kāi)始喇伯,按照層級(jí)順序喊儡,依次向外遍歷

舉例

JSON.parse('{"p": 5}', function (k, v) {
    if(k === '') return v; // 如果到了最頂層,則直接返回屬性值稻据,
    return v * 2; // 否則將屬性值變?yōu)樵瓉?lái)的 2 倍管宵。
}); // { p: 10 }

JSON.parse('{"1": 1, "2": 2,"3": {"4": 4, "5": {"6": 6}}}', function (k, v) {
    console.log(k); // 輸出當(dāng)前的屬性名,從而得知遍歷順序是從內(nèi)向外的,
                    // 最后一個(gè)屬性名會(huì)是個(gè)空字符串箩朴。
    return v; // 返回原始屬性值岗喉,相當(dāng)于沒(méi)有傳遞 reviver 參數(shù)。
}); // 1 2 4 6 5 3 ''

注意:不允許用逗號(hào)作為結(jié)尾

// both will throw a SyntaxError
JSON.parse("[1, 2, 3, 4, ]");
JSON.parse('{"foo" : 1, }');

原生 js 實(shí)現(xiàn)

var myJson = {
  parse: function (jsonStr) {
    return (new Function('return ' + jsonStr))();
  },
  stringify: function (jsonObj) {
    var result = '',
      curVal;
    if (jsonObj === null) {
      return String(jsonObj);
    }
    switch (typeof jsonObj) {
      case 'number':
      case 'boolean':
        return String(jsonObj);
      case 'string':
        return '"' + jsonObj + '"';
      case 'undefined':
      case 'function':
        return undefined;
    }

    switch (Object.prototype.toString.call(jsonObj)) {
      case '[object Array]':
        result += '[';
        for (var i = 0, len = jsonObj.length; i < len; i++) {
          curVal = JSON.stringify(jsonObj[i]);
          result += (curVal === undefined ? null : curVal) + ",";
        }
        if (result !== '[') {
          result = result.slice(0, -1);
        }
        result += ']';
        return result;
      case '[object Date]':
        return '"' + (jsonObj.toJSON ? jsonObj.toJSON() : jsonObj.toString()) + '"';
      case '[object RegExp]':
        return "{}";
      case '[object Object]':
        result += '{';
        for (i in jsonObj) {
          if (jsonObj.hasOwnProperty(i)) {
            curVal = JSON.stringify(jsonObj[i]);
            if (curVal !== undefined) {
              result += '"' + i + '":' + curVal + ',';
            }
          }
        }
        if (result !== '{') {
          result = result.slice(0, -1);
        }
        result += '}';
        return result;

      case '[object String]':
        return '"' + jsonObj.toString() + '"';
      case '[object Number]':
      case '[object Boolean]':
        return jsonObj.toString();
    }
  }
};

說(shuō)明:JSON.parse() 在這里是利用 new Function() 擁有字符串參數(shù)特性,即能動(dòng)態(tài)編譯 js 代碼的能力≡是疲可參考神奇的eval()與new Function()

JSON.parse() 其他方式實(shí)現(xiàn):

利用 eval() 實(shí)現(xiàn)坦敌,盡量避免在不必要的情況下使用酣衷。 eval() '惡名昭彰',擁有執(zhí)行代碼的能力(可能被惡意使用,帶來(lái)安全問(wèn)題),除此之外纸颜,不能利用預(yù)編譯的優(yōu)勢(shì)進(jìn)行性能優(yōu)化,會(huì)比較慢绎橘。

var json = eval('(' + jsonStr + ')');

還有其他方式胁孙,比如遞歸,可參考:JSON.parse 三種實(shí)現(xiàn)方式

言盡于此称鳞,當(dāng)然涮较,不止于此(你懂得)。歡迎大家來(lái)補(bǔ)充~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冈止,一起剝皮案震驚了整個(gè)濱河市狂票,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熙暴,老刑警劉巖闺属,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異周霉,居然都是意外死亡掂器,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)诗眨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人孕讳,你說(shuō)我怎么就攤上這事匠楚。” “怎么了厂财?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵芋簿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我璃饱,道長(zhǎng)与斤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮撩穿,結(jié)果婚禮上磷支,老公的妹妹穿的比我還像新娘。我一直安慰自己食寡,他們只是感情好雾狈,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著抵皱,像睡著了一般善榛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呻畸,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天移盆,我揣著相機(jī)與錄音,去河邊找鬼伤为。 笑死咒循,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钮呀。 我是一名探鬼主播剑鞍,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼爽醋!你這毒婦竟也來(lái)了蚁署?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蚂四,失蹤者是張志新(化名)和其女友劉穎光戈,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體遂赠,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡久妆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跷睦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筷弦。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抑诸,靈堂內(nèi)的尸體忽然破棺而出烂琴,到底是詐尸還是另有隱情,我是刑警寧澤蜕乡,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布奸绷,位于F島的核電站,受9級(jí)特大地震影響层玲,放射性物質(zhì)發(fā)生泄漏号醉。R本人自食惡果不足惜反症,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畔派。 院中可真熱鬧铅碍,春花似錦、人聲如沸父虑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)士嚎。三九已至呜魄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莱衩,已是汗流浹背爵嗅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笨蚁,地道東北人睹晒。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像括细,于是被迫代替她去往敵國(guó)和親伪很。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359