JavaScript 高級程序設(shè)計(jì)(book 3rd edition)

  • <script>元素位置

一般慣例是在<head>元素中包含所有的<script>元素,但是這就意味著必須等到全部的javascript代碼都被下載叔收、解析和執(zhí)行完成后齿穗,才開始呈現(xiàn)頁面部分:

<!DOCTYPE html>
<html>
<head>
<script></script>
</head>
<body></body>
</html>

為了避免這個(gè)問題,現(xiàn)代Web應(yīng)用程序一般把全部<scripy>元素放在<body>內(nèi)饺律,且放在頁面的內(nèi)容后面:

<!DOCTYPE html>
<html>
<head></head>
<body>
//
<script></script>
</body>
</html>

但是也會(huì)看到把 <script>元素放在 </body>標(biāo)簽之后 </html> 標(biāo)簽之前的窃页。這么寫的愿景是頁面內(nèi)容加載完再加載js?
按照HTML5標(biāo)準(zhǔn)中的HTML語法規(guī)則复濒,如果在</body>后再出現(xiàn)<script>或任何元素的開始標(biāo)簽脖卖,都是parse error,瀏覽器會(huì)忽略之前的</body>巧颈,即視作仍舊在body內(nèi)畦木。所以實(shí)際效果和寫在</body>之前是沒有區(qū)別的≡曳海總之十籍,這種寫法雖然也能work,但是并沒有帶來任何額外好處唇礁,實(shí)際上出現(xiàn)這樣的寫法很可能是誤解了“將script放在頁面最末端”的教條勾栗。所以還是不要這樣寫為好。雖然將<script>寫在</body>之后盏筐,但最終的DOM樹里围俘,<script>元素還是會(huì)成為body的子節(jié)點(diǎn),這一點(diǎn)很容易在firebug等調(diào)試器里驗(yàn)證。

  • 延遲腳本

<script>元素的defer屬性界牡。
這個(gè)屬性的用途是標(biāo)明腳本在執(zhí)行時(shí)不會(huì)影響頁面的構(gòu)造簿寂,也就是說,腳本會(huì)被延遲到整個(gè)頁面都解析完畢后再運(yùn)行欢揖。因此,在<script>元素中設(shè)置defer屬性奋蔚,相當(dāng)于告訴瀏覽器立即下載她混,但延遲執(zhí)行。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" defer="defer" scr="path/jsname.js"></script>
</head>
<body></body>
</html>

defer屬性只適用于外部腳本文件泊碑,會(huì)忽略嵌入腳本設(shè)置的defer屬性坤按。

  • 異步腳本

html5為<script>元素定義了async屬性。與defer類似的是馒过,都用于改變處理腳本的行為臭脓,且也只適用于外部腳本。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" async="async" scr="path/jsname1.js"></script>
<script type="text/javascript" async="async" scr="path/jsname2.js"></script>
</head>
<body></body>
</html>

上面代碼中腹忽,第二個(gè)腳本可能會(huì)先于第一個(gè)腳本執(zhí)行来累,因此,使用了async就要確保腳本間互不依賴窘奏。
指定async屬性的目的是不讓頁面等待兩個(gè)腳本下載和執(zhí)行嘹锁,從而異步加載頁面其他內(nèi)容,所以也建議不要在加載期間修改DOM着裹。
異步腳本一定會(huì)在頁面的load事件前執(zhí)行领猾,但可能會(huì)在DOMContentLoad事件觸發(fā)之前或之后執(zhí)行。

  • 重排序方法

兩個(gè)可以直接使用的重排序方法:

  • reverse():反轉(zhuǎn)數(shù)組項(xiàng)的順序骇扇;
  • sort():默認(rèn)情況下按升序排列數(shù)組項(xiàng)摔竿。但是為了實(shí)現(xiàn)排序,sort()方法會(huì)調(diào)用每個(gè)數(shù)組項(xiàng)的toString()方法少孝,然后比較得到的字符串继低。所以,即使數(shù)組中的每一項(xiàng)都是數(shù)值稍走,該方法比較的也是字符串郁季。
var values=[0, 1, 5, 10, 15];
values.sort();
console.log(values);   //0, 1, 10, 15, 5

所以sort()方法可以接收一個(gè)比較函數(shù)作為參數(shù),一邊自定義比較方法钱磅。該標(biāo)膠函數(shù)要接收兩個(gè)參數(shù)梦裂,如果要求第一個(gè)參數(shù)應(yīng)該位于第二個(gè)參數(shù)之前則返回一個(gè)負(fù)數(shù),如果兩個(gè)參數(shù)相等則返回0盖淡,如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)參數(shù)之后則返回一個(gè)正數(shù)年柠。

function compare(value1, value2){
  if(value1 < value2) return -1;
  else if(value1 > value2) return 1;
  else return 0;
}
var values=[0, 1, 5, 10, 15];
values.sort(compare);
console.log(values);    //0, 1 , 5, 10, 15
//所以compare也可以這樣實(shí)現(xiàn):
function compare(value1, value2){
  return value1-value2;
}
  • 基本包裝

為了便于操作基本數(shù)據(jù)類型,ECMAScript提供了3個(gè)特殊的引用類型:Boolean,Number冗恨,String答憔。每當(dāng)讀取一個(gè)基本類型值的時(shí)候,后臺(tái)就會(huì)創(chuàng)建一個(gè)對應(yīng)的基本包裝類型的對象掀抹,從而能夠讓我們調(diào)用一些方法來對這些基本數(shù)據(jù)進(jìn)行操作虐拓。

var s1 = "some example";
var s2 = s1.substring(2);

上例中s1是一個(gè)字符串基本類型,但是第二行卻調(diào)用了一個(gè)方法傲武,我們知道基本類型值不是對象蓉驹,邏輯上是不該有自己的方法的。其實(shí)揪利,系統(tǒng)為了實(shí)現(xiàn)該操作态兴,在后臺(tái)自動(dòng)完成了一系列的處理。在讀取模式中訪問字符串時(shí)疟位,后臺(tái)都會(huì)自動(dòng)完成下列處理:

  • 創(chuàng)建String類型的一個(gè)實(shí)例瞻润;
  • 在實(shí)例上調(diào)用指定的方法;
  • 銷毀這個(gè)實(shí)例甜刻。
    所以绍撞,上面的兩行實(shí)際是這樣執(zhí)行的:
var s1="some example";
var s3=new String(s1);
var s2=s3.substring(2);
s3=null;
console.log(s2);   //me example

經(jīng)過此番處理,基本的字符串值就變得跟對象一樣了得院。而且楚午,上面三個(gè)步驟也適用于Boolean和Number。

引用類型與基本包裝類型的主要區(qū)別就是對象的生存期尿招。使用new操作符創(chuàng)建的引用類型的實(shí)例矾柜,在執(zhí)行流離開當(dāng)前作用域之前都一直保存在內(nèi)存中。而自動(dòng)創(chuàng)建的基本包裝類型的對象就谜,則只存在于一行代碼的執(zhí)行瞬間怪蔑,而后立即被銷毀,這也意味著我們不能在運(yùn)行時(shí)為基本類型值添加屬性和方法丧荐。

var s1 = "some example";
s1.color = "red";
console.log(s1.color);        //undefined
console.log(s1);     some example
var ss=new String("some example");
ss.color="red";
console.log(ss);   //String {0: "s", 1: "o", 2: "m", 3: "e", 4: " ", 5: "e", 6: "x", 7: "a", 8: "m", 9: "p", 10: "l", 11: "e", color: "red", length: 12, [[PrimitiveValue]]: "some example"}
  • Boolean

他們的建議是永遠(yuǎn)不要使用Boolean對象缆瓣。

var falseObject = new Boolean(false);
var result = falseObject && true;
console.log(result); // true
//---
var falseValue = false;
var result = falseValue && true;
console.log(result); //false

出現(xiàn)上面這個(gè)差異的原因是:代碼中是對falseObject而不是對它的值(false)進(jìn)行求值。布爾表達(dá)式中的所有對象都會(huì)被轉(zhuǎn)換為true虹统,因此falseObject對象在布爾表達(dá)式中代表的是true而不是它的初值false弓坞。

  • Function

  • 函數(shù)內(nèi)部屬性

函數(shù)內(nèi)兩個(gè)特殊對象:argumentsthis
arguments的主要用途是保存函數(shù)參數(shù)车荔,但是它還有一個(gè)重要屬性callee渡冻,該屬性是一個(gè)指針,指向擁有這個(gè)arguments對象的函數(shù)忧便。

//例如階乘函數(shù)
function factorial(num){
 if(num<=1) return 1;
else{return num*factorial(num-1);}
}
//使用arguments.callee
function factorial(num){
 if(num<=1) return 1;
else{return num*arguments.callee(num-1);}
}

上面的函數(shù)在函數(shù)有名字族吻,且函數(shù)名字不變的情況下是沒問題的。但是這個(gè)函數(shù)的執(zhí)行與函數(shù)名factorial緊緊耦合在一起,為了消除這種耦合超歌,使用arguments.callee砍艾。
////////////////////////////////////////////////////////
另一個(gè)函數(shù)對象的屬性:caller。這個(gè)屬性中保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用巍举。如果是在全局作用域中調(diào)用當(dāng)前函數(shù)脆荷,它的值為null。

function outer(){
      inner();
}
function inner(){
      console.log(inner.caller);
}
outer(); //輸出outer的源代碼懊悯,因?yàn)槭莖uter調(diào)用的inner蜓谋。所以為了去耦合也可以通過arguments.callee.caller來實(shí)現(xiàn)。
  • 函數(shù)屬性和方法

每個(gè)函數(shù)都包含兩個(gè)屬性:length定枷,prototype孤澎。
length表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)届氢。
prototype保存它們所有實(shí)例方法的真正所在欠窒。

  • apply() 與 call()

這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)的this對象的值退子。
apply()方法接收兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行函數(shù)的作用域岖妄,另一個(gè)是參數(shù)數(shù)組,可以是Array的實(shí)例也可以是arguments對象寂祥。
call()與apply()的區(qū)別在參數(shù)不同:第一個(gè)也是this荐虐,而后面的參數(shù)是逐個(gè)列舉傳遞。
事實(shí)上丸凭,apply()和call()最大的用武之地福扬,真正強(qiáng)大的地方是能擴(kuò)充函數(shù)賴以運(yùn)行的作用域(類似C++的多態(tài)?):

window.color = "red";
var object = {"color":"blue"};
function sayColor(){
  alert(this.color);
}
sayColor();     //red
sayColor.call(this);   //red
sayColor.call(window);   //red
sayColor.call(object);    //blue

使用call()或apply()來擴(kuò)充作用域的好處惜犀,就是對象與方法不需要有任何耦合關(guān)系铛碑。

  • bind

這個(gè)方法會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例,其this值會(huì)被綁定到傳給bind()函數(shù)的值(類似C++多態(tài)預(yù)編譯時(shí)多態(tài)虽界?)

window.color = "red";
var object = {"color": "blue"};
function sayColor(){
  alert(this.color);
}
var objectSayColor=sayColor.bind(object);//方法綁定到對象汽烦,并返回一個(gè)函數(shù)實(shí)例
objectSayColor();  //blue
  • 創(chuàng)建對象

  • 工廠模式

工廠模式就是可批量生產(chǎn)嘍,就是以函數(shù)的方式創(chuàng)建對象莉御,用函數(shù)來封裝特定接口創(chuàng)建對象的細(xì)節(jié):

function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
  alert(this.name);
};
return o;
}
var persion1 = createPerson("Greg",27,"Doctor");

但是該方式?jīng)]有解決對象識別問題(怎樣獲得一個(gè)對象的類型)撇吞。

  • 構(gòu)造函數(shù)模式

創(chuàng)建自定義的構(gòu)造函數(shù)意味著可以將它的實(shí)例標(biāo)識為一種特定的類型,而這正是構(gòu)造函數(shù)模式勝過工廠模式的地方礁叔。

function Person(name,age,job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName= function(){
  alert(this.name);
  };
}
var person1 = new Person("Greg",27,"Doctor");

與工廠模式相似牍颈,但是明顯不同。
創(chuàng)建的對象person1隱含一個(gè)constructor屬性琅关,該屬性指向Person:

alert(person1.constructor == Person);//true

但是颂砸,檢測對象類型還是instanceof操作符更可靠一些。

alert(person1 instanceof Object);//true
alert(person1 instanceof Person);//true
  • 構(gòu)造函數(shù)與普通函數(shù)

兩者的區(qū)別就是在調(diào)用是產(chǎn)生的,否則構(gòu)造函數(shù)就是普通函數(shù)人乓,普通函數(shù)也可作為構(gòu)造函數(shù)調(diào)用:

//構(gòu)造
var person = new Person("Greg",27,"Doctor");
person.sayName();//Greg
//普通函數(shù)調(diào)用
Person("Greg",27,"Doctor");
window.sayName();//Greg
//在另一個(gè)對象的作用域中調(diào)用
var o = new Object();
Person.call(o,"Greg",27,"Doctor");
o.sayName();//Greg
  • 原型模式

我們創(chuàng)建的每一個(gè)函數(shù)都有一個(gè)prototype(原型)屬性勤篮,這個(gè)屬性是一個(gè)指針,指向一個(gè)對象色罚。
而這個(gè)對象的用途是用來包含所有實(shí)例共享的屬性和方法碰缔。
使用原型對象的好處就是讓所有對象實(shí)例共享它所包含的屬性和方法。
同時(shí)戳护,這也是它最大的缺點(diǎn)金抡。

function Persion(){}
Person.prototype.name = "Greg";
Person.prototype.age = 27;
Person.prototype.sayName = function(){alert(this.name);};
var person1 = new Person();
person1.sayName();//Greg
var person2 = new Person();
person2.sayName();//Greg
alert(person1.sayName == person2.sayName);//true,共享所有屬性和方法
理解原型對象

創(chuàng)建一個(gè)新函數(shù)腌且,就會(huì)創(chuàng)建一個(gè)prototype屬性梗肝,這個(gè)屬性指向函數(shù)的原型對象。
默認(rèn)情況下所有原型對象都會(huì)獲得夜歌constructor屬性铺董,這個(gè)屬性包含一個(gè)指向prototype屬性所在函數(shù)的指針单旁。
以前例來說:
Person.prototype.constructor指向Person雕沿。
當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例,該實(shí)例內(nèi)部將會(huì)包含一個(gè)指針,指向構(gòu)造函數(shù)的原型對象杖剪,ECMA5管這個(gè)指針叫[[Prototype]]涨冀,在瀏覽器控制臺(tái)看到的是proto玄组。
要明確的一點(diǎn)是障贸,這個(gè)連接存在于實(shí)例與構(gòu)造函數(shù)的原型對象之間,而不是存在于實(shí)例與構(gòu)造函數(shù)之間确垫。

s.PNG

圖中弓颈,展示了Person構(gòu)造函數(shù),Person的原型屬性以及Person現(xiàn)有兩個(gè)實(shí)例之間的關(guān)系删掀。
Person.prototype指向原型對象翔冀,
Person.prototype.constructor指回Person,
原型對象中包含constructor及后來添加的其他屬性爬迟,
Person的每一個(gè)實(shí)例都包含一個(gè)內(nèi)部屬性橘蜜,該屬性僅僅指向Person.prototype。

isPrototypeOf

確定對象實(shí)例是否來自某個(gè)對象原型
alert(Person.prototype.isPrototypeOf(person1));//true

Object.getPrototypeOf()

返回對象實(shí)例的[[Prototype]]值付呕。
alert(Object.getPrototypeOf(person1) == Person.prototype);//true
alert(Object.getPrototypeOf(person1).name);//Greg

hasOwnPrototype()

這里涉及到讀取對象屬性時(shí)的搜索順序计福,
搜索先從對象實(shí)例本身開始,如果實(shí)例中存在就返回該屬性的值徽职,
否則繼續(xù)向上搜索指針指向的原型對象象颖。
所以,如果我們在實(shí)例中重寫覆蓋了原型中的值姆钉,那么返回的就是新值说订,而非共享的屬性值抄瓦。

person1.name = "Nicholas";
alert(person1.name);//Nicholas   來自實(shí)例
alert(person2.name);//Greg   來自原型

所以,實(shí)例中重寫的值只是屏蔽對原型中同名屬性的訪問陶冷,而不是修改原型中的那個(gè)屬性钙姊。
如要改回,使用delete操作符就可以完全刪除實(shí)例中的同名屬性埂伦。
使用hasOwnProperty()方法可以檢測一個(gè)屬性是存在于實(shí)例中還是原型中煞额,
這個(gè)方法只在給定屬性存在于對象實(shí)例中時(shí)才會(huì)返回true。

alert(person2.hasOwnProperty("name"));//false   實(shí)例中不存在
alert(person1.hasOwnProperty("name"));//true   實(shí)例中存在
delete person1.name;
alert(person1.hasOwnProperty("name"));//false   實(shí)例中不存在

通過該方法就能確定什么時(shí)候訪問的是示例屬性沾谜,什么時(shí)候是原型屬性膊毁。


s.PNG
原型與in操作符

in操作符會(huì)在能夠通過對象訪問給定屬性時(shí)返回true,無論該屬性存在于實(shí)例中還是原型中基跑,

alert("name" in person1);//true

所以婚温,結(jié)合hasOwnProperty()就能判讀屬性存在的位置。

Object.keys()

獲取對象上所有可枚舉的實(shí)力屬性
參數(shù)為對象媳否,返回一個(gè)包含所有可枚舉屬性的字符串?dāng)?shù)組栅螟。

var keys = Object.keys(Person.prototype);//["name","age","sayName"],因?yàn)閏onstructor的Enumrable默認(rèn)為false
person1.name = "Bob";
var keys1 = Object.keys(person1);//["name"]  只輸出實(shí)例的
getOwnPrototypeNames()

返回所有實(shí)例屬性逆日,無論是否可枚舉嵌巷。

  • 更常用的原型語法

從原型prototype的定義可以知道萄凤,prototype下是一個(gè)對象室抽。
所以:

function Person(){}
Person.prototype = {
    name :"Greg",
    age : 27,
    sayName : function(){alert(this.name);}
};

但是這樣又出現(xiàn)一個(gè)問題,
這樣定義后靡努,constructor不再指向Person了坪圾,
因?yàn)檫@種定義方法本質(zhì)上是對原prototype的完全重寫(所以,對原型完全重寫后的原型就是另一個(gè)原型了)惑朦,而創(chuàng)建新的prototype對象兽泄,這個(gè)對象也會(huì)自動(dòng)重新獲得constructor,所以新的consytructor就不指回原Person了漾月,

var friend = new Person();
alert(friend instanceof Object);//true
alert(friend instanceof Person);//true
alert(friend.constructor == Person );//false

解決方法病梢,
如果constructor的值很重要,就重新指定回原值

Person.prototype = {
  constructor:Person,
  ........
  ........
}
  • 原型的動(dòng)態(tài)性

重寫整個(gè)原型梁肿,就會(huì)切斷構(gòu)造函數(shù)與最初原型之間的聯(lián)系蜓陌,這個(gè)上面有提到。

  • 原型對象的問題

開始有提到吩蔑,原型中所有的屬性是被實(shí)例共享的钮热,
這種共享對函數(shù)很適合,
對于那些包含基本值的屬性也可以烛芬,同名屬性屏蔽隧期,
但是對于引用類型值的屬性飒责,問題就突出了:

function Person(){}
Person.prototype = {
  name = "Bob",
  age = 27,
  friends: ["Sheldy", "Court"]
};
var person1 = new Person();
var person2 = new Person();
person1.friend.push("Vans");
alert(person1.friends);//Sheldy,Court,Vans
alert(person2.friends);//Sheldy,Court,Vans
alert(person1.friends == person2.friends);//true
  • 組合使用構(gòu)造函數(shù)模式和原型模式

解決上面遇到的問題
同時(shí),也是創(chuàng)建自定義類型的最常用方式仆潮。
構(gòu)造函數(shù)模式來定義示例的非共享屬性宏蛉,
原型模式來定義方法和共享的屬性。
結(jié)果性置,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本檐晕,
同時(shí)又共享著對方法的引用,最大限度的節(jié)省了內(nèi)存蚌讼。
而且辟灰,這種混合模式還支持向構(gòu)造函數(shù)傳遞參數(shù)。

function Person(name,age,friends){
  this.name = name;
  this.age = age;
  this,friends = friends;
}
Person.prototype = {
  constructor: Person,
  sayName:function(){alert(this.name);}
}
  • 繼承

  • js只支持實(shí)現(xiàn)繼承篡石,而且主要是依靠原型鏈實(shí)現(xiàn)芥喇。
  • 原型鏈
  • 先跳過
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市凰萨,隨后出現(xiàn)的幾起案子继控,更是在濱河造成了極大的恐慌,老刑警劉巖胖眷,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件武通,死亡現(xiàn)場離奇詭異,居然都是意外死亡珊搀,警方通過查閱死者的電腦和手機(jī)冶忱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來境析,“玉大人囚枪,你說我怎么就攤上這事±拖” “怎么了链沼?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沛鸵。 經(jīng)常有香客問我括勺,道長,這世上最難降的妖魔是什么曲掰? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任疾捍,我火速辦了婚禮,結(jié)果婚禮上蜈缤,老公的妹妹穿的比我還像新娘拾氓。我一直安慰自己,他們只是感情好底哥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布咙鞍。 她就那樣靜靜地躺著房官,像睡著了一般。 火紅的嫁衣襯著肌膚如雪续滋。 梳的紋絲不亂的頭發(fā)上翰守,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音疲酌,去河邊找鬼蜡峰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛朗恳,可吹牛的內(nèi)容都是我干的湿颅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粥诫,長吁一口氣:“原來是場噩夢啊……” “哼油航!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怀浆,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谊囚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后执赡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镰踏,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年沙合,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奠伪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灌诅,死狀恐怖芳来,靈堂內(nèi)的尸體忽然破棺而出含末,到底是詐尸還是另有隱情猜拾,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布佣盒,位于F島的核電站挎袜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肥惭。R本人自食惡果不足惜盯仪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜜葱。 院中可真熱鬧全景,春花似錦、人聲如沸牵囤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炕贵,卻和暖如春梆奈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背称开。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工亩钟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鳖轰。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓清酥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蕴侣。 傳聞我的和親對象是個(gè)殘疾皇子总处,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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