第二章:詞法作用域

特別說明分井,為便于查閱,文章轉(zhuǎn)自https://github.com/getify/You-Dont-Know-JS

在第一章中撤奸,我們將“作用域”定義為一組規(guī)則啸驯,它主宰著 引擎 如何通過標(biāo)識(shí)符名稱在當(dāng)前的 作用域,或者在包含它的任意 嵌套作用域 中來查詢一個(gè)變量英上,

作用域的工作方式有兩種占統(tǒng)治地位的模型炭序。其中的第一種是最最常見,在絕大多數(shù)的編程語言中被使用的苍日。它稱為 詞法作用域惭聂,我們將深入檢視它。另一種仍然被一些語言(比如 Bash 腳本相恃,Perl 中的一些模式辜纲,等等)使用的模型,稱為 動(dòng)態(tài)作用域拦耐。

動(dòng)態(tài)作用域在附錄A中講解耕腾。我在這里提到它僅僅是為詞法作用域提供一個(gè)對(duì)比,而詞法作用域是 JavaScript 所采用的作用域模型杀糯。

詞法分析時(shí)

正如我們?cè)诘谝徽轮杏懻摰纳ò常瑯?biāo)準(zhǔn)語言編譯器的第一個(gè)傳統(tǒng)步驟稱為詞法分析(也就是分詞)。如果你回憶一下固翰,詞法分析處理是檢查一串源代碼字符狼纬,并給 token 賦予語法含義作為某種有狀態(tài)解析的輸出羹呵。

正是這個(gè)概念給理解詞法作用域是什么提供了基礎(chǔ),它也是這個(gè)名字的淵源畸颅。

要定義它有點(diǎn)兒兜圈子担巩,詞法作用域是在詞法分析時(shí)被定義的作用域。換句話說没炒,詞法作用域是基于涛癌,你,在寫程序時(shí)送火,變量和作用域的塊兒在何處被編寫決定的拳话,因此它在詞法分析器處理你的代碼時(shí)(基本上)是固定不變的。

注意: 我們將會(huì)稍稍看到有一些方法可以騙過詞法作用域种吸,從而在詞法分析器處理過后改變它弃衍,但是這些方法都是使人皺眉頭的。事實(shí)上公認(rèn)的最佳實(shí)踐是坚俗,將詞法作用域看作是僅僅依靠詞法的镜盯,因此自然而然地完全是編寫時(shí)決定的。

讓我們考慮這段代碼:

function foo(a) {

    var b = a * 2;

    function bar(c) {
        console.log( a, b, c );
    }

    bar(b * 3);
}

foo( 2 ); // 2 4 12

在這個(gè)代碼實(shí)例中有三個(gè)固有的嵌套作用域猖败。將這些作用域考慮為套在一起的氣泡可能有助于思考速缆。

氣泡1 包圍著全局作用域,它里面只有一個(gè)標(biāo)識(shí)符:foo恩闻。

氣泡2 包圍著作用域 foo艺糜,它含有三個(gè)標(biāo)識(shí)符:abarb幢尚。

氣泡3 包圍著作用域 bar破停,它里面只包含一個(gè)標(biāo)識(shí)符:c

作用域氣泡是根據(jù)作用域的塊兒被寫在何處定義的尉剩,一個(gè)嵌套在另一個(gè)內(nèi)部真慢,等等。在下一章中理茎,我們將討論作用域的不同單位晤碘,但是就現(xiàn)在來說,讓我們認(rèn)為每一個(gè)函數(shù)創(chuàng)建了一個(gè)新的作用域氣泡功蜓。

bar 的氣泡完全被包含在 foo 的氣泡中,因?yàn)椋ǘ抑灰驗(yàn)椋┻@就是我們選擇定義函數(shù) bar 的位置宠蚂。

注意這些嵌套的氣泡是嚴(yán)格嵌套的式撼。我們沒有討論氣泡可以跨越邊界的維恩圖(Venn diagrams)。換句話說求厕,沒有那個(gè)函數(shù)的氣泡可以同時(shí)(部分地)存在于另外兩個(gè)外部的作用域氣泡中著隆,就像沒有函數(shù)可以部分地存在于它的兩個(gè)父函數(shù)中一樣扰楼。

查詢

這些作用域氣泡的結(jié)構(gòu)和相對(duì)位置完全解釋了 引擎 在查找一個(gè)標(biāo)識(shí)符時(shí),它需要查看的所有地方美浦。

在上面的代碼段中弦赖,引擎 執(zhí)行語句 console.log(..) 并開始查找三個(gè)被引用的變量 abc浦辨。它首先從最內(nèi)部的作用域氣泡開始蹬竖,也就是 bar(..) 函數(shù)的作用域。在這里它找不到 a流酬,所以它向上走一層币厕,到外面下一個(gè)最近的作用域氣泡,foo(..) 的作用域芽腾。它在這里找到了 a旦装,于是它就使用這個(gè) a。同樣的事情也發(fā)生在 b 身上摊滔。但是對(duì)于 c阴绢,它在 bar(..) 內(nèi)部就找到了。

如果在 bar(..) 內(nèi)部和 foo(..) 內(nèi)部都有一個(gè) c艰躺,那么 console.log(..) 語句將會(huì)找到并使用 bar(..) 中的那一個(gè)呻袭,絕不會(huì)到達(dá) foo(..) 中的那一個(gè)。

一旦找到第一個(gè)匹配描滔,作用域查詢就停止了棒妨。相同的標(biāo)識(shí)符名稱可以在嵌套作用域的多個(gè)層中被指定,這稱為“遮蔽(shadowing)”(內(nèi)部的標(biāo)識(shí)符“遮蔽”了外部的標(biāo)識(shí)符)含长。無論如何遮蔽券腔,作用域查詢總是從當(dāng)前被執(zhí)行的最內(nèi)側(cè)的作用域開始,向外/向上不斷查找拘泞,直到第一個(gè)匹配才停止纷纫。

注意: 全局變量也自動(dòng)地是全局對(duì)象(在瀏覽器中是 window,等等)的屬性陪腌,所以不直接通過全局變量的詞法名稱辱魁,而通過將它作為全局對(duì)象的一個(gè)屬性引用來間接地引用,是可能的诗鸭。

window.a

這種技術(shù)給出了訪問全局變量的方法染簇,沒有它全局變量將因?yàn)楸徽诒味豢稍L問。然而强岸,被遮蔽的非全局變量是無法訪問的锻弓。

不管函數(shù)是從 哪里 被調(diào)用的,也不論它是 如何 被調(diào)用的蝌箍,它的詞法作用域是由這個(gè)函數(shù)被聲明的位置 唯一 定義的青灼。

詞法作用域查詢 僅僅 在處理頭等標(biāo)識(shí)符時(shí)實(shí)施暴心,比如 ab杂拨,和 c专普。如果你在一段代碼中擁有一個(gè) foo.bar.baz 的引用,詞法作用域查詢將在查找 foo 標(biāo)識(shí)符時(shí)實(shí)施弹沽,但一旦定位這個(gè)變量檀夹,對(duì)象屬性訪問規(guī)則將會(huì)分別接管 barbaz 屬性的解析。

欺騙詞法作用域

如果詞法作用域是由函數(shù)被聲明的位置唯一定義的贷币,而且這個(gè)位置完全是一個(gè)編寫時(shí)的決定击胜,那么怎么可能有辦法在運(yùn)行時(shí)“修改”(也就是,作弊欺騙)詞法作用域呢役纹?

JavaScript 有兩種這樣的機(jī)制偶摔。在廣大的社區(qū)中它們都等同地被認(rèn)為是讓人皺眉頭的,在你代碼中使用它們是一種差勁兒的做法促脉。但是關(guān)于它們的常見的爭論經(jīng)常錯(cuò)過了最重要的一點(diǎn):欺騙詞法作用域會(huì)導(dǎo)致更低下的性能辰斋。

在我講解性能的問題以前,先讓我們看看這兩種機(jī)制是如何工作的瘸味。

eval

JavaScript 中的 eval(..) 函數(shù)接收一個(gè)字符串作為參數(shù)值宫仗,并將這個(gè)字符串的內(nèi)容看作是好像它已經(jīng)被實(shí)際編寫在程序的那個(gè)位置上。換句話說旁仿,你可以用編程的方式在你編寫好的代碼內(nèi)部生成代碼藕夫,而且你可以運(yùn)行這個(gè)生成的代碼,就好像它在編寫時(shí)就已經(jīng)在那里了一樣枯冈。

如果以這種觀點(diǎn)來評(píng)價(jià) eval(..)毅贮,那么 eval(..) 是如何允許你修改詞法作用域環(huán)境應(yīng)當(dāng)是很清楚的:欺騙并假裝這個(gè)編寫時(shí)(也就是,詞法)代碼一直就在那里尘奏。

eval(..) 被執(zhí)行的后續(xù)代碼行中滩褥,引擎 將不會(huì)“知道”或“關(guān)心”前面的代碼是被動(dòng)態(tài)翻譯的,而且因此修改了詞法作用域環(huán)境炫加。引擎 將會(huì)像它一直做的那樣瑰煎,簡單地進(jìn)行詞法作用域查詢。

考慮如下代碼:

function foo(str, a) {
    eval( str ); // 作弊俗孝!
    console.log( a, b );
}

var b = 2;

foo( "var b = 3;", 1 ); // 1 3

eval(..) 調(diào)用的位置上酒甸,字符串 "var b = 3" 被看作是一直就存在在那里的代碼。因?yàn)檫@個(gè)代碼恰巧聲明了一個(gè)新的變量 b赋铝,它就修改了現(xiàn)存的 foo(..) 的詞法作用域插勤。事實(shí)上,就像上面提到的那樣,這個(gè)代碼實(shí)際上在 foo(..) 內(nèi)部創(chuàng)建了變量 b饮六,它遮蔽了聲明在外部(全局)作用域中的 b

當(dāng) console.log(..) 調(diào)用發(fā)生時(shí)苛蒲,它會(huì)在 foo(..) 的作用域中找到 ab卤橄,而且絕不會(huì)找到外部的 b。這樣臂外,我們就打印出 "1 3" 而不是一般情況下的 "1 2"窟扑。

注意: 在這個(gè)例子中,為了簡單起見漏健,我們傳入的“代碼”字符串是固定的文字嚎货。但是它可以通過根據(jù)你的程序邏輯將字符拼接在一起,很容易地以編程方式創(chuàng)建蔫浆。eval(..) 通常被用于執(zhí)行動(dòng)態(tài)創(chuàng)建的代碼殖属,因?yàn)閯?dòng)態(tài)地對(duì)一段實(shí)質(zhì)上源自字符串字面值的靜態(tài)代碼進(jìn)行求值,并不會(huì)比直接編寫這樣的代碼帶來更多真正的好處瓦盛。

默認(rèn)情況下洗显,如果 eval(..) 執(zhí)行的代碼字符串包含一個(gè)或多個(gè)聲明(變量或函數(shù))的話,這個(gè)動(dòng)作就會(huì)修改這個(gè) eval(..) 所在的詞法作用域原环。技術(shù)上講挠唆,eval(..) 可以通過種種技巧(超出了我們這里的討論范圍)被“間接”調(diào)用,而使它在全局作用域的上下文中執(zhí)行嘱吗,以此修改全局作用域玄组。但不論那種情況,eval(..) 都可以在運(yùn)行時(shí)修改一個(gè)編寫時(shí)的詞法作用域谒麦。

注意: 當(dāng) eval(..) 被用于一個(gè)操作它自己的詞法作用域的 strict 模式程序時(shí)俄讹,在 eval(..) 內(nèi)部做出的聲明不會(huì)實(shí)際上修改包圍它的作用域。

function foo(str) {
   "use strict";
   eval( str );
   console.log( a ); // ReferenceError: a is not defined
}

foo( "var a = 2" );

在 JavaScript 中還有其他的工具擁有與 eval(..) 非常類似的效果弄匕。setTimeout(..)setInterval(..) 可以 為它們各自的第一個(gè)參數(shù)值接收一個(gè)字符串颅悉,其內(nèi)容將會(huì)被 eval 為一個(gè)動(dòng)態(tài)生成的函數(shù)的代碼。這種老舊的迁匠,遺產(chǎn)行為早就被廢棄了剩瓶。別這么做!

new Function(..) 函數(shù)構(gòu)造器類似地為它的 最后 一個(gè)參數(shù)值接收一個(gè)代碼字符串城丧,來把它轉(zhuǎn)換為一個(gè)動(dòng)態(tài)生成的函數(shù)(前面的參數(shù)值延曙,如果有的話,將作為新函數(shù)的形式參數(shù))亡哄。這種函數(shù)構(gòu)造器語法要比 eval(..) 稍稍安全一些枝缔,但在你的代碼中它仍然應(yīng)當(dāng)被避免。

在你的代碼中動(dòng)態(tài)生成代碼的用例少的不可思議,因?yàn)樵谛阅苌系牡雇耸沟眠@種能力幾乎總是得不償失愿卸。

with

JavaScript 的另一個(gè)使人皺眉頭(而且現(xiàn)在被廢棄了A榱佟),而且可以欺騙詞法作用域的特性是 with 關(guān)鍵字趴荸。有許多種合法的方式可以講解 with儒溉,但是我在此選擇從它如何與詞法作用域互動(dòng)并影響詞法作用域的角度來講解它。

講解 with 的常見方式是作為一種縮寫发钝,來引用一個(gè)對(duì)象的多個(gè)屬性顿涣,而 不必 每次都重復(fù)對(duì)象引用本身。

例如:

var obj = {
    a: 1,
    b: 2,
    c: 3
};

//  重復(fù)“obj”顯得更“繁冗”
obj.a = 2;
obj.b = 3;
obj.c = 4;

// “更簡單”的縮寫
with (obj) {
    a = 3;
    b = 4;
    c = 5;
}

然而酝豪,這里發(fā)生的事情要比只是一個(gè)對(duì)象屬性訪問的便捷縮寫要多得多涛碑。考慮如下代碼:

function foo(obj) {
    with (obj) {
        a = 2;
    }
}

var o1 = {
    a: 3
};

var o2 = {
    b: 3
};

foo( o1 );
console.log( o1.a ); // 2

foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 -- 哦孵淘,全局作用域被泄漏了蒲障!

在這個(gè)代碼示例中,創(chuàng)建了兩個(gè)對(duì)象 o1o2夺英。一個(gè)有 a 屬性晌涕,而另一個(gè)沒有。foo(..) 函數(shù)接收一個(gè)對(duì)象引用 obj 作為參數(shù)值痛悯,并在這個(gè)引用上調(diào)用 with (obj) {..}余黎。在 with 塊兒內(nèi)部,我們制造了一個(gè)變量 a 的看似是普通詞法引用的東西载萌,實(shí)際上是一個(gè) LHS 引用(見第一章)惧财,并將值 2 賦予它。

當(dāng)我們傳入 o1 時(shí)扭仁,賦值 a = 2 找到屬性 o1.a 并賦予它值 2垮衷,正如在后續(xù)的 console.log(o1.a) 語句中反映出的那樣。然而乖坠,當(dāng)我們傳入 o2搀突,因?yàn)樗鼪]有 a 屬性,沒有這樣的屬性被創(chuàng)建熊泵,所以 o2.a 還是 undefined仰迁。

但是之后我們注意到一個(gè)特別的副作用,賦值 a = 2 創(chuàng)建了一個(gè)全局變量 a顽分。這怎么可能徐许?

with 語句接收一個(gè)對(duì)象,這個(gè)對(duì)象有0個(gè)或多個(gè)屬性卒蘸,并 將這個(gè)對(duì)象視為好像它是一個(gè)完全隔離的詞法作用域雌隅,因此這個(gè)對(duì)象的屬性被視為在這個(gè)“作用域”中詞法定義的標(biāo)識(shí)符。

注意: 盡管一個(gè) with 塊兒將一個(gè)對(duì)象視為一個(gè)詞法作用域,但是在 with 塊兒內(nèi)部的一個(gè)普通 var 聲明將不會(huì)歸于這個(gè) with 塊兒的作用域恰起,而是歸于包含它的函數(shù)作用域修械。

如果 eval(..) 函數(shù)接收一個(gè)含有一個(gè)或多個(gè)聲明的代碼字符串,它就會(huì)修改現(xiàn)存的詞法作用域检盼,而 with 語句實(shí)際上是從你傳遞給它的對(duì)象中憑空制造了一個(gè) 全新的詞法作用域祠肥。

以這種方式理解的話,當(dāng)我們傳入 o1 時(shí) with 語句聲明的“作用域”就是 o1梯皿,而且這個(gè)“作用域”擁有一個(gè)對(duì)應(yīng)于 o1.a 屬性的“標(biāo)識(shí)符”。但當(dāng)我們使用 o2 作為“作用域”時(shí)县恕,它里面沒有這樣的 a “標(biāo)識(shí)符”东羹,于是 LHS 標(biāo)識(shí)符查詢(見第一章)的普通規(guī)則發(fā)生了。

“作用域” o2 中沒有忠烛,foo(..) 的作用域中也沒有属提,甚至連全局作用域中都沒有找到標(biāo)識(shí)符 a,所以當(dāng) a = 2 被執(zhí)行時(shí)美尸,其結(jié)果就是自動(dòng)全局變量被創(chuàng)建(因?yàn)槲覀儧]有在 strict 模式下)冤议。

with 在運(yùn)行時(shí)將一個(gè)對(duì)象和它的屬性轉(zhuǎn)換為一個(gè)帶有“標(biāo)識(shí)符”的“作用域”,這個(gè)奇怪想法有些燒腦师坎。但是對(duì)于我們看到的結(jié)果來說恕酸,這是我能給出的最清晰的解釋。

注意: 除了使用它們是個(gè)壞主意以外胯陋,eval(..)with 都受Strict模式的影響(制約)蕊温。with 干脆就不允許使用,而雖然 eval(..) 還保有其核心功能遏乔,但各種間接形式的或不安全的 eval(..) 是不允許的义矛。

性能

通過在運(yùn)行時(shí)修改,或創(chuàng)建新的詞法作用域盟萨,eval(..)with 都可以欺騙編寫時(shí)定義的詞法作用域凉翻。

你可能會(huì)問,那又有什么大不了的捻激?如果它們提供了更精巧的功能和編碼靈活性制轰,那它們不是 好的 特性嗎?不铺罢。

JavaScript 引擎 在編譯階段期行許多性能優(yōu)化工作艇挨。其中的一些優(yōu)化原理都?xì)w結(jié)為實(shí)質(zhì)上在進(jìn)行詞法分析時(shí)可以靜態(tài)地分析代碼,并提前決定所有的變量和函數(shù)聲明都在什么位置韭赘,這樣在執(zhí)行期間就可以少花些力氣來解析標(biāo)識(shí)符缩滨。

但如果 引擎 在代碼中發(fā)現(xiàn)一個(gè) eval(..)with,它實(shí)質(zhì)上就不得不 假定 自己知道的所有的標(biāo)識(shí)符的位置可能是無效的,因?yàn)樗豢赡茉谠~法分析時(shí)就知道你將會(huì)向eval(..)傳遞什么樣的代碼來修改詞法作用域脉漏,或者你可能會(huì)向with傳遞的對(duì)象有什么樣的內(nèi)容來創(chuàng)建一個(gè)新的將被查詢的詞法作用域苞冯。

換句話說,悲觀地看侧巨,如果 eval(..)with 出現(xiàn)舅锄,那么它 做的幾乎所有的優(yōu)化都會(huì)變得沒有意義,所以它就會(huì)簡單地根本不做任何優(yōu)化司忱。

你的代碼幾乎肯定會(huì)趨于運(yùn)行的更慢皇忿,只因?yàn)槟阍诖a的任何地方引入了一個(gè)了 eval(..)with。無論 引擎 將在努力限制這些悲觀臆測的副作用上表現(xiàn)得多么聰明坦仍,都沒有任何辦法可以繞過這個(gè)事實(shí):沒有優(yōu)化鳍烁,代碼就運(yùn)行的更慢。

復(fù)習(xí)

詞法作用域意味著作用域是由編寫時(shí)函數(shù)被聲明的位置的決策定義的繁扎。編譯器的詞法分析階段實(shí)質(zhì)上可以知道所有的標(biāo)識(shí)符是在哪里和如何聲明的幔荒,并如此在執(zhí)行期間預(yù)測它們將如何被查詢。

在 JavaScript 中有兩種機(jī)制可以“欺騙”詞法作用域:eval(..)with梳玫。前者可以通過對(duì)一個(gè)擁有一個(gè)或多個(gè)聲明的“代碼”字符串進(jìn)行求值爹梁,來(在運(yùn)行時(shí))修改現(xiàn)存的詞法作用域。后者實(shí)質(zhì)上是通過將一個(gè)對(duì)象引用看作一個(gè)“作用域”提澎,并將這個(gè)對(duì)象的屬性看作作用域中的標(biāo)識(shí)符姚垃,(同樣,也是在運(yùn)行時(shí))創(chuàng)建一個(gè)全新的詞法作用域盼忌。

這些機(jī)制的缺點(diǎn)是莉炉,它壓制了 引擎 在作用域查詢上進(jìn)行編譯期優(yōu)化的能力,因?yàn)?引擎 不得不悲觀地假定這樣的優(yōu)化是無效的碴犬。這兩種特性的結(jié)果就是代碼 會(huì)運(yùn)行的更慢絮宁。不要使用它們。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末服协,一起剝皮案震驚了整個(gè)濱河市绍昂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偿荷,老刑警劉巖窘游,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異跳纳,居然都是意外死亡忍饰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門寺庄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艾蓝,“玉大人力崇,你說我怎么就攤上這事∮” “怎么了亮靴?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長于置。 經(jīng)常有香客問我茧吊,道長,這世上最難降的妖魔是什么八毯? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任搓侄,我火速辦了婚禮,結(jié)果婚禮上话速,老公的妹妹穿的比我還像新娘休讳。我一直安慰自己,他們只是感情好尿孔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筹麸,像睡著了一般活合。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上物赶,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天白指,我揣著相機(jī)與錄音,去河邊找鬼酵紫。 笑死告嘲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赊豌,長吁一口氣:“原來是場噩夢啊……” “哼扩借!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起务甥,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后僧界,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡臭挽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年捂襟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欢峰。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葬荷,死狀恐怖涨共,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闯狱,我是刑警寧澤煞赢,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站哄孤,受9級(jí)特大地震影響照筑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘦陈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一凝危、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晨逝,春花似錦蛾默、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趁窃,卻和暖如春牧挣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背醒陆。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工瀑构, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刨摩。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓寺晌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親澡刹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呻征,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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