深入理解JS中的淺拷貝與深拷貝

一、棧內(nèi)存與堆內(nèi)存

棧內(nèi)存與堆內(nèi)存 玖姑、淺拷貝與深拷貝愕秫,可以說是前端程序員的內(nèi)功,要知其然焰络,知其所以然戴甩。

1、棧與棧內(nèi)存

棧的定義
  • 后進(jìn)者先出闪彼,先進(jìn)者后出甜孤,簡(jiǎn)稱 后進(jìn)先出(LIFO),這就是典型的結(jié)構(gòu)。
  • 新添加的或待刪除的元素都保存在棧的末尾缴川,稱作棧頂茉稠,另一端就叫棧底
  • 在棧里二跋,新元素都靠近棧頂战惊,舊元素都接近棧底。
  • 從棧的操作特性來看扎即,是一種 操作受限 的線性表吞获,只允許在一端插入和刪除數(shù)據(jù)。
  • 不包含任何元素的棧稱為空棧谚鄙。
  • 棧也被用在編程語言的編譯器和內(nèi)存中保存變量各拷、方法調(diào)用等,比如函數(shù)的調(diào)用棧闷营。
棧內(nèi)存
  • 它們存儲(chǔ)的值都有固定的大小烤黍,保存在棧內(nèi)存空間,通過按值訪問傻盟,并由系統(tǒng)自動(dòng)分配和自動(dòng)釋放速蕊。
  • 這樣帶來的好處就是,內(nèi)存可以及時(shí)得到回收娘赴,相對(duì)于堆來說规哲,更加容易管理內(nèi)存空間。
  • 主要用于存儲(chǔ)各種基本數(shù)據(jù)類型的變量诽表,以及對(duì)象變量的指針唉锌。
  • JavaScript 中的 BooleanNull竿奏、Undefined袄简、NumberString泛啸、Symbol绿语、BigInt 都是基本數(shù)據(jù)類型。

2平痰、堆與堆內(nèi)存

堆的定義
  • 堆數(shù)據(jù)結(jié)構(gòu)是一種樹狀結(jié)構(gòu)汞舱。
  • 它的存取數(shù)據(jù)的方式,與書架與書非常相似宗雇。我們不關(guān)心書的放置順序是怎樣的昂芜,只需知道書的名字就可以取出我們想要的書了。
  • 好似在 JSON 格式的數(shù)據(jù)中赔蒲,我們存儲(chǔ)的 key-value 是可以無序的泌神,只要知道 key良漱,就能取出這個(gè) key 對(duì)應(yīng)的 value

堆與棧比較

  • 堆是動(dòng)態(tài)分配內(nèi)存欢际,內(nèi)存大小不一母市,也不會(huì)自動(dòng)釋放。
  • 棧是自動(dòng)分配相對(duì)固定大小的內(nèi)存空間损趋,并由系統(tǒng)自動(dòng)釋放患久。
  • 棧,線性結(jié)構(gòu)浑槽,后進(jìn)先出蒋失,便于管理。
  • 堆桐玻,一個(gè)混沌篙挽,雜亂無章,方便存儲(chǔ)和開辟內(nèi)存空間镊靴。
堆內(nèi)存

引用類型(如對(duì)象铣卡、數(shù)組、函數(shù)等)是保存在堆內(nèi)存中的對(duì)象偏竟,值大小不固定煮落,棧內(nèi)存中存放的該對(duì)象的訪問地址指向堆內(nèi)存中的對(duì)象,JavaScript 不允許直接訪問堆內(nèi)存中的位置踊谋,因此操作對(duì)象時(shí)州邢,實(shí)際操作對(duì)象的引用。
JavaScript 中的 Object褪子、Array、Function骗村、RegExp嫌褪、Date 是引用類型。

堆內(nèi)存與棧內(nèi)存比較

棧內(nèi)存 堆內(nèi)存
存儲(chǔ)基礎(chǔ)數(shù)據(jù)類型 存儲(chǔ)引用數(shù)據(jù)類型
按值訪問 按引用訪問
存儲(chǔ)的值大小固定 存儲(chǔ)的值大小不定胚股,可動(dòng)態(tài)調(diào)整
由系統(tǒng)自動(dòng)分配內(nèi)存空間 由代碼進(jìn)行指定分配
空間小笼痛,運(yùn)行效率高 空間大,運(yùn)行效率相對(duì)較低
先進(jìn)后出琅拌,后進(jìn)先出 無序存儲(chǔ)缨伊,可根據(jù)引用直接獲取
棧內(nèi)存堆內(nèi)存

棧內(nèi)存中的變量一般都是已知大小或者有范圍上限的,算作一種簡(jiǎn)單存儲(chǔ)进宝。而堆內(nèi)存存儲(chǔ)的對(duì)象類型數(shù)據(jù)對(duì)于大小這方面刻坊,一般是未知的。這就是為什么null作為一個(gè)object類型的變量卻存儲(chǔ)在棧內(nèi)存中的原因吧党晋。

當(dāng)我們定義一個(gè)const obj ={name:'king'}對(duì)象的時(shí)候谭胚,我們說的常量obj其實(shí)是指針徐块,就是變量obj的值不允許改變,也就是變量obj指向的堆內(nèi)存的地址不能改變灾而,但是胡控,該堆內(nèi)存地址內(nèi)數(shù)據(jù)本身的大小或?qū)傩允强梢愿淖兊摹?/p>

既然知道了const在內(nèi)存中的存儲(chǔ),那么const旁趟、let定義的變量不能二次定義的流程也就比較容易猜出來了昼激,每次使用const或者let去初始化一個(gè)變量的時(shí)候,會(huì)首先遍歷當(dāng)前的內(nèi)存棧锡搜,看看有沒有重名變量橙困,有的話就返回錯(cuò)誤。

二余爆、數(shù)據(jù)類型

JS中纷宇,數(shù)據(jù)分為基本數(shù)據(jù)類型(StringNumber蛾方、Boolean像捶、NullUndefined桩砰、Symbol拓春、BigInt)和引用數(shù)據(jù)類型(ObjectFunction亚隅、class)硼莽。

  • 基本數(shù)據(jù)類型是直接存儲(chǔ)在棧(Stack)內(nèi)存中的數(shù)據(jù)
  • 引用數(shù)據(jù)類型棧內(nèi)存存儲(chǔ)的是該對(duì)象的引用地址,對(duì)象的真實(shí)數(shù)據(jù)存儲(chǔ)在堆內(nèi)存中
    引用數(shù)據(jù)類型在棧內(nèi)存中存儲(chǔ)了引用地址(也叫指針)煮纵,該引用地址或指針指向了堆內(nèi)存中實(shí)際數(shù)據(jù)的地址懂鸵。


    引用數(shù)據(jù)類型存儲(chǔ)

1、基本數(shù)據(jù)類型的存儲(chǔ)

變量名和值都儲(chǔ)存在棧內(nèi)存中

let num = 10;
let newnum = num;

那么該num變量在棧內(nèi)存中的存儲(chǔ)如下

基本數(shù)據(jù)類型存儲(chǔ)

變量num和值10都存儲(chǔ)在棧內(nèi)存中行疏,num =10;讓變量num指向數(shù)字10;而newnum =num是將變量newnum存儲(chǔ)在棧內(nèi)存中匆光,并且讓該變量指向新的值數(shù)字10。此時(shí)酿联,變量num和變量newnum沒有任何關(guān)系终息。注意 棧內(nèi)存的賦值都是賦值,newnum = num是指將變量num賦值給新變量newnum;而不是把變量num賦值給變量newnum贞让。

基本數(shù)據(jù)類型值是不可變的
let a = 1;
console.log(++a);

其實(shí)這個(gè)時(shí)候并不是變量a 指向的 1 直接加了 1周崭,而是 新建了一個(gè) 1+1 = 2 的值,再將 a 指向這個(gè)新建出來的 2喳张,原來的那個(gè) 1 并沒有發(fā)生改變续镇,留由垃圾回收機(jī)制處理。也就是說不是 a 指向的值發(fā)生了改變蹲姐,而是 a 變量指針指向了一個(gè)新的值磨取,這就是基本類型的值是不可變的人柿。

2、引用數(shù)據(jù)類型的存儲(chǔ)

變量名儲(chǔ)存在棧內(nèi)存中忙厌,值儲(chǔ)存在堆內(nèi)存中凫岖,但是堆內(nèi)存中會(huì)提供一個(gè)引用地址指向堆內(nèi)存中的值,而這個(gè)地址是儲(chǔ)存在棧內(nèi)存中的逢净。

let ary = [1, 2, 3];
let newary = ary;

那么該ary變量在內(nèi)存中的存儲(chǔ)如下

引用數(shù)據(jù)類型存儲(chǔ)

引用數(shù)據(jù)類型值是可變的
let obj = { name: 'king' };
obj.name = '偶爾平凡';
console.log(obj)
//{ name: '偶爾平凡' }

引用數(shù)據(jù)類型占據(jù)空間大哥放,大小不固定,儲(chǔ)存在堆內(nèi)存爹土,但是指向該引用數(shù)據(jù)類型的變量指針「a」是儲(chǔ)存在棧內(nèi)存中甥雕。 當(dāng)解釋器尋找引用值時(shí),會(huì)首先檢索其在棧中的地址胀茵,取得地址后從堆中獲得實(shí)體社露。

var a = new String("123");
var b = String("123");
var c = "123";
console.log(a == b, a === b, b == c, b === c, a == c, a === c);
//           true     false    true    true     true    false

我們可以看到new一個(gè)String,出來的是對(duì)象琼娘,而直接字面量賦值和工廠模式出來的都是字符串峭弟。

let a = new String("123");
let b = new String("123");
console.log(a == b, a === b);
console.log(null === null);
//false false
//true

我們知道,變量a 和變量b都是存儲(chǔ)在棧內(nèi)存中的脱拼,但是變量a指向一個(gè)對(duì)象瞒瘸,假設(shè)該對(duì)象的堆內(nèi)存地址AA00,變量b執(zhí)行一個(gè)新的對(duì)象,該新對(duì)象的堆內(nèi)存地址BB00熄浓,也就是變量a的值為AA00情臭,變量b的值為BB00,所以變量a和變量b的值不同。而null是存儲(chǔ)在棧內(nèi)存的赌蔑,所以null === nulltrue俯在。

let a = null;
let b = null;
console.log(a === b);//true

3、基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的銷毀

基本類型在當(dāng)前執(zhí)行環(huán)境結(jié)束時(shí)銷毀娃惯,而引用類型不會(huì)隨執(zhí)行環(huán)境結(jié)束而銷毀朝巫,只有當(dāng)所有引用它的變量不存在時(shí)這個(gè)對(duì)象才被垃圾回收機(jī)制回收。

三石景、淺拷貝和深拷貝的區(qū)別

基本數(shù)據(jù)類型都是深拷貝,無需討論拙吉。引用數(shù)據(jù)類中的淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針潮孽,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊堆內(nèi)存筷黔。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象往史,新對(duì)象跟原對(duì)象不共享堆內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象佛舱。淺拷貝和深拷貝椎例,都是圍繞堆棧內(nèi)存展開的挨决,一個(gè)是處理值,一個(gè)是處理指針订歪。

四脖祈、淺拷貝的實(shí)現(xiàn)方式

1、直接賦值

let A = {
  name: "king",
  data: {
    age: 20,
  },
};
let B = {};
B = A;
B.name = "偶爾平凡";
console.log(A);
//{ name: '偶爾平凡', data: { age: 20 } }

2刷晋、Object.assign()

這是ES6中新增的對(duì)象方法盖高,對(duì)它不了解的見ES6對(duì)象新增方法,它可以實(shí)現(xiàn)第一層的“深拷貝”眼虱,但無法實(shí)現(xiàn)多層的深拷貝喻奥。

第一層“深拷貝”:就是對(duì)于A對(duì)象下所有的屬性和方法都進(jìn)行了深拷貝,但是當(dāng)A對(duì)象下的屬性如data是對(duì)象時(shí)捏悬,它拷貝的是地址撞蚕,也就是淺拷貝,這種拷貝方式還是屬于淺拷貝过牙。

多層深拷貝:能將A對(duì)象下所有的屬性甥厦,及時(shí)屬性是對(duì)象,也能夠深拷貝出來抒和,讓A和B相互獨(dú)立矫渔,這種叫才叫深拷貝。

let A = {
  name: "king",
  data: {
    age: 20,
  },
};
let B = {};
Object.assign(B, A);
B.name = "偶爾平凡";
B.data.age = 15;
console.log(A);
console.log(B);
//{ name: 'king', data: { age: 15 } }
//{ name: '偶爾平凡', data: { age: 15 } }

3摧莽、擴(kuò)展運(yùn)算符

let obj = { name: "king", age: 10, se: { sex: 0 } };
let newobj = { ...obj };
newobj.name = "偶爾平凡";
newobj.se.sex = 1;
console.log(obj);
console.log(newobj);
//{ name: 'king', age: 10, se: { sex: 1 } }
//{ name: '偶爾平凡', age: 10, se: { sex: 1 } }

4庙洼、Array.prototype.concat()

let arr = [
  1,
  3,
  {
    name: "king",
  },
];
let arr2 = arr.concat();
arr2[1] = 10;
arr2[2].name = "偶爾平凡";
console.log(arr);
console.log(arr2);
//[ 1, 3, { name: '偶爾平凡' } ]
//[ 1, 10, { name: '偶爾平凡' } ]

5、Array.prototype.slice()

let arr = [
  1,
  3,
  {
    name: "king",
  },
];
let arr2 = arr.slice();
arr2[1] = 10;
arr2[2].name = "偶爾平凡";
console.log(arr);
console.log(arr2);
//[ 1, 3, { name: '偶爾平凡' } ]
//[ 1, 10, { name: '偶爾平凡' } ]

關(guān)于Array的slice和concat方法的補(bǔ)充說明:Array的slice和concat方法不修改原數(shù)組镊辕,只會(huì)返回一個(gè)淺復(fù)制了原數(shù)組中的元素的一個(gè)新數(shù)組油够。

原數(shù)組的元素會(huì)按照下述規(guī)則拷貝:

  1. 如果該元素是個(gè)對(duì)象引用(不是實(shí)際的對(duì)象),slice 會(huì)拷貝這個(gè)對(duì)象引用到新的數(shù)組里征懈。兩個(gè)對(duì)象引用都引用了同一個(gè)對(duì)象石咬。如果被引用的對(duì)象發(fā)生改變,則新的和原來的數(shù)組中的這個(gè)元素也會(huì)發(fā)生改變卖哎。
  2. 對(duì)于字符串鬼悠、數(shù)字及布爾值來說(不是 String、Number 或者 Boolean 對(duì)象)亏娜,slice 會(huì)拷貝這些值到新的數(shù)組里焕窝。在別的數(shù)組里修改這些字符串或數(shù)字或是布爾值,將不會(huì)影響另一個(gè)數(shù)組维贺。

五它掂、深拷貝的實(shí)現(xiàn)方式

1、JSON.parse(JSON.stringify())

let arr = [1, 2, { name: "king" }];
let arr2 = JSON.parse(JSON.stringify(arr));
arr2[1] = 10;
arr2[2].name = "偶爾平凡";
console.log(arr);
console.log(arr2);
//[ 1, 2, { name: 'king' } ]
//[ 1, 10, { name: '偶爾平凡' } ]

這種方法雖然可以實(shí)現(xiàn)數(shù)組或?qū)ο笊羁截愃萜荒芴幚砗瘮?shù)虐秋。這是因?yàn)?JSON.stringify() 方法是將一個(gè)JavaScript值(對(duì)象或者數(shù)組)轉(zhuǎn)換為一個(gè)JSON字符串榕茧,不能接受函數(shù)。

let arr = [1, 2, { name: "king", fn: function() {} }];
let arr2 = JSON.parse(JSON.stringify(arr));
console.log(arr);
console.log(arr2);
//[ 1, 2, { name: 'king', fn: [Function: fn] } ]
//[ 1, 2, { name: 'king' } ]

2客给、手寫遞歸函數(shù)實(shí)現(xiàn)

第1步:假設(shè)遞歸函數(shù)已寫好用押。

const deepClone = (value) => {
}

第2步:處理第一層的情況,也就是一般的情況起愈。比如對(duì)方傳遞了一個(gè)null或者undefined進(jìn)來可以處理的只恨。

const deepClone = (value) => {
  if (value == null) {
    return value;
  }
};
let result = deepClone(null);
let result1 = deepClone(undefined);
console.log(result,result1);//null undefined

第3步:還是處理一般的情況,比如對(duì)方傳遞了一個(gè)普通數(shù)據(jù)類型或許函數(shù)抬虽,直接返回該值即可搞定官觅。

const deepClone = (value) => {
  if (value == null) {
    return value;
  }
  if (typeof value !== "object") {
    return value;
  }
};
let result = deepClone('abc');
console.log(result);//abc

第4步:還是處理一般的情況,比如對(duì)方傳遞了一個(gè)正則類型或許時(shí)間類型的值阐污,那么返回一個(gè)新正則或時(shí)間即可休涤。

const deepClone = (value) => {
  if (value == null) {
    return value;
  }
  if (typeof value !== "object") {
    return value;
  }
  if (value instanceof RegExp) {
    return new RegExp(value);
  }
  if (value instanceof Date) {
    return new Date(value);
  }
};

第5步:處理傳進(jìn)來的是對(duì)象或者數(shù)組的情況了。

const deepClone = (value) => {
  if (value == null) {
    return value;
  }
  if (typeof value !== "object") {
    return value;
  }
  if (value instanceof RegExp) {
    return new RegExp(value);
  }
  if (value instanceof Date) {
    return new Date(value);
  }
  let instance = new value.constructor(); //創(chuàng)建一個(gè)新的空對(duì)象或數(shù)組
  for (let key in value) {
    instance[key] = value[key];
  }
  return instance;
};
let obj = { name: "king", age: 10 };
let result = deepClone(obj);
result.name = "偶爾平凡";
console.log(result);//{ name: '偶爾平凡', age: 10 }
console.log(obj);//{ name: 'king', age: 10 }

第6步:我們上面處理的對(duì)象是單層對(duì)象笛辟,如果對(duì)象內(nèi)的值 value[key] 又是一個(gè)對(duì)象怎么辦呢功氨,這時(shí)候,才開始考慮遞歸即可手幢。因?yàn)榈谝粚拥那闆r我們已經(jīng)處理好了捷凄,第二層重復(fù)第一層就OK了。

//深拷貝
const deepClone = (value) => {
  if (value == null) {
    //排除null 和 undefine的情況,直接返回
    return value;
  }
  if (typeof value !== "object") {
    //基本數(shù)據(jù)類型和函數(shù)的情況直接返回即可
    return value;
  }
  if (value instanceof RegExp) {
    //正則的情況,返回新的正則即可
    return new RegExp(value);
  }
  if (value instanceof Date) {
    return new Date(value);
  }
  //處理對(duì)象或者數(shù)組的情況,new 創(chuàng)建新的空對(duì)象或數(shù)組
  let instance = new value.constructor();
  for (let key in value) {
    if (value.hasOwnProperty(key)) {
      //排除原型鏈上的屬性或方法
      instance[key] = deepClone(value[key]);
    }
  }
  return instance;
};
let obj = { name: "king", age: 10, se: { sex: 0 }, fn: () => {} };
let newobj = deepClone(obj);
newobj.name = '偶爾平凡';
newobj.se.sex = 1;
console.log(newobj);
console.log(obj);
//{ name: '偶爾平凡', age: 10, se: { sex: 1 }, fn: [Function: fn] }
//{ name: 'king', age: 10, se: { sex: 0 }, fn: [Function: fn] }

確實(shí)围来,實(shí)現(xiàn)了深拷貝跺涤,感覺很完美,但是监透,遇到下面這種情況桶错,會(huì)直接跑死,進(jìn)入死循環(huán)了胀蛮。

let obj = { a: 1 };
obj.b = obj;
let newobj =deepClone(obj);
//RangeError: Maximum call stack size exceeded 內(nèi)存爆裂而亡

最終修改后的內(nèi)容

const deepClone = (value, hash = new WeakMap => {
  if (value == null) {
    //排除null 和 undefine的情況,直接返回
    return value;
  }
  if (typeof value !== "object") {
    //基本數(shù)據(jù)類型和函數(shù)的情況直接返回即可
    return value;
  }
  if (value instanceof RegExp) {
    //正則的情況,返回新的正則即可
    return new RegExp(value);
  }
  if (value instanceof Date) {
    return new Date(value);
  }
  //處理對(duì)象或者數(shù)組的情況,new 創(chuàng)建新的空對(duì)象或數(shù)組
  let instance = new value.constructor();
  if (hash.has(value)) {
    //在hash 中查詢一下是否存在過院刁,如果存在就把以前拷貝的返回
    return hash.get(value);
  }
  hash.set(value, instance); //沒有存過就放進(jìn)去
  for (let key in value) {
    if (value.hasOwnProperty(key)) {
      //排除原型鏈上的屬性或方法
      instance[key] = deepClone(value[key], hash);
      //將hash繼續(xù)傳遞下去,保證每次能拿到以前拷貝的結(jié)果
    }
  }
  return instance;
};

let obj = { a: 1 };
obj.b = obj;
let newobj = deepClone(obj);
console.log(newobj);
//{ a: 1, b: [Circular] }

注意小知識(shí)點(diǎn):

//字典 Map 和 WeakMap 區(qū)別
//Map 中的key為對(duì)象粪狼,如果該對(duì)象外部人工銷毀了退腥,該對(duì)象在Map中并沒有銷毀
//堆內(nèi)存存放的 { name: "king" } 的地址為 OXFF00
// 地址OXFF00 分別賦值給了 obj以及map中去
//變量obj重新賦值了null;但是map中的地址還在再榄,所以堆內(nèi)存中的對(duì)象不會(huì)銷毀
let obj = { name: "king" };
let map = new Map();
map.set(obj, 0);
obj = null;
console.log(map);
console.log(obj);
//Map { { name: 'king' } => 0 }
//null
//obj 重新賦值后阅虫,WeakMap中的obj也改變,也就是若引用
let obj = { name: "king" };
let map = new WeakMap();
map.set(obj, 0);
obj = null;
console.log(map);
console.log(obj);
//WeakMap { <items unknown> }
//null

六不跟、遞歸基礎(chǔ)知識(shí)

1、什么是遞歸

在JavaScript程序中米碰,函數(shù)直接或間接調(diào)用自己窝革。通過某個(gè)條件判斷跳出結(jié)構(gòu)购城,有了跳出才有結(jié)果。

2虐译、遞歸寫法的步驟

  1. 假設(shè)遞歸函數(shù)已經(jīng)寫好了瘪板。
  2. 尋找遞推關(guān)系。
  3. 將遞推關(guān)系的結(jié)構(gòu)轉(zhuǎn)換為遞歸體
  4. 將臨界條件加入到遞歸體中(一定要加臨界條件漆诽,某則陷入死循環(huán)侮攀,內(nèi)存泄漏)

3、遞歸示例

求1-100的和厢拭,用遞歸該怎么寫呢兰英?按照遞歸的步驟來即可
1、假設(shè)遞歸函數(shù)已經(jīng)寫好了供鸠,即為sum(100),就是求1-100的和畦贸。
2、尋找遞推關(guān)系楞捂,就是nn-1的關(guān)系 sum(n) ==sum(n-1) +n薄坏。

let result = sum(100);
let result = sum(99) +100;

3、將遞歸結(jié)構(gòu)轉(zhuǎn)換為遞歸體寨闹。

function sum(n) {
  return sum(n - 1) + n;
}

4胶坠、加入臨界條件,防止死循環(huán)繁堡。求100 轉(zhuǎn)換為 求99 求99 轉(zhuǎn)換為 求98 求98 轉(zhuǎn)換為 求97 … 求2 轉(zhuǎn)換為 求1 求1 轉(zhuǎn)換為 求1 即 sum(1) = 1

function sum(n) {
  if (n == 1) return 1;
  return sum(n - 1) + n;
}
console.log(sum(100));//5050
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沈善,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子帖蔓,更是在濱河造成了極大的恐慌矮瘟,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塑娇,死亡現(xiàn)場(chǎng)離奇詭異澈侠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)埋酬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門哨啃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人写妥,你說我怎么就攤上這事拳球。” “怎么了珍特?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵祝峻,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)莱找,這世上最難降的妖魔是什么酬姆? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮奥溺,結(jié)果婚禮上辞色,老公的妹妹穿的比我還像新娘。我一直安慰自己浮定,他們只是感情好相满,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桦卒,像睡著了一般立美。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闸盔,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天悯辙,我揣著相機(jī)與錄音,去河邊找鬼迎吵。 笑死躲撰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的击费。 我是一名探鬼主播拢蛋,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蔫巩!你這毒婦竟也來了谆棱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤圆仔,失蹤者是張志新(化名)和其女友劉穎垃瞧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坪郭,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡个从,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歪沃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗦锐。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沪曙,靈堂內(nèi)的尸體忽然破棺而出奕污,到底是詐尸還是另有隱情,我是刑警寧澤液走,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布碳默,位于F島的核電站贾陷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嘱根。R本人自食惡果不足惜昵宇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望儿子。 院中可真熱鬧,春花似錦砸喻、人聲如沸柔逼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愉适。三九已至,卻和暖如春癣漆,著一層夾襖步出監(jiān)牢的瞬間维咸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工惠爽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留癌蓖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓婚肆,卻偏偏與公主長(zhǎng)得像租副,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子较性,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容