JavaScript中實(shí)現(xiàn)繼承的方式總結(jié)

我們?cè)?a href="http://www.reibang.com/p/375b0646cbd1" target="_blank">對(duì)象創(chuàng)建模式中討論過(guò)盛泡,對(duì)象創(chuàng)建的模式就是定義對(duì)象模板的方式钝满。有了模板以后,我們就可以輕松地創(chuàng)建多個(gè)結(jié)構(gòu)相同的對(duì)象了绞绒。
繼承就是對(duì)象創(chuàng)建模式的擴(kuò)展,我們需要在舊模板的基礎(chǔ)上榕暇,添加新的特性蓬衡,使之成為一個(gè)新的模板喻杈。

為了更加迎合程序員的“直覺(jué)”,本篇文章有時(shí)使用“父類”來(lái)指代“父對(duì)象的模板”狰晚。但是讀者應(yīng)該明確:JavaScript沒(méi)有類系統(tǒng)筒饰。

1. 純?cè)玩溊^承

純?cè)玩溊^承的思想就是讓所有需要繼承的屬性都在原型鏈上(而不會(huì)在實(shí)例對(duì)象自己身上)。
原型鏈?zhǔn)菍?shí)現(xiàn)繼承的重要工具家肯,以下是單純使用原型鏈實(shí)現(xiàn)繼承的方式:

function SuperType() {
    this.property = 1;
}
// 將方法放在原型上龄砰,以便所有實(shí)例共用,避免重復(fù)定義
SuperType.prototype.getSuperValue = function() {
    return this.property;
};

function SubType() {
    this.subproperty = 2;
}
SubType.prototype = new SuperType();
// 將方法放在原型上讨衣,以便所有實(shí)例共用换棚,避免重復(fù)定義
SubType.prototype.getSubValue = function() {
    return this.subproperty;
};
var instance = new SubType();
console.log(instance.getSuperValue());  // 1
console.log(instance instanceof SubType);   // true
console.log(instance instanceof SuperType); // true

雖然上面使用了構(gòu)造函數(shù)與new關(guān)鍵字,但是在純?cè)玩溊^承中反镇,繼承屬性的原理與它們一點(diǎn)關(guān)系也沒(méi)有固蚤,父類的所有屬性都在原型鏈上。使用構(gòu)造函數(shù)只是為了代碼簡(jiǎn)潔歹茶,同時(shí)還可以讓我們使用instanceof進(jìn)行對(duì)象識(shí)別(詳見(jiàn)上一篇文章)夕玩。
實(shí)際上,我們可以不使用構(gòu)造函數(shù)與new關(guān)鍵字來(lái)實(shí)現(xiàn)純?cè)玩溊^承:

// 定義父對(duì)象的原型
var superPrototype = {
    getSuperValue: function() {
        return this.property;
    }
};
// 定義父對(duì)象的工廠方法
function createSuper() {
    var superInstance = Object.create(superPrototype);
    superInstance.property = 1;
    return superInstance;
}
// 定義子對(duì)象的原型
var subPrototype = createSuper();
subPrototype.getSubValue = function() {
    return this.subproperty;
};
// 定義子對(duì)象的工廠方法
function createSub() {
    var subInstance = Object.create(subPrototype);
    subInstance.subproperty = 2;
    return subInstance;
}
// 創(chuàng)建子對(duì)象
var instance = createSub();
console.log(instance.getSuperValue());  // 1
console.log(instance.getSubValue());  // 2

通過(guò)這種方式實(shí)現(xiàn)純?cè)玩溊^承的作用完全相同惊豺,原型鏈也完全相同燎孟,只不過(guò)不能使用instanceof和constructor指針了(因?yàn)樗鼈冃枰獦?gòu)造函數(shù))。

所有需要繼承的屬性都在原型鏈上(而不會(huì)在實(shí)例對(duì)象自己身上)尸昧,這是純?cè)玩溊^承與后面繼承方式的最大不同揩页。

純?cè)玩溊^承的缺陷

  • 在使用構(gòu)造函數(shù)的實(shí)現(xiàn)方式中,我們無(wú)法給父類的構(gòu)造函數(shù)傳遞參數(shù)烹俗。也就是上例中的這條語(yǔ)句:SubType.prototype = new SuperType();爆侣,這句話是在創(chuàng)建子對(duì)象之前就執(zhí)行的,所以我們無(wú)法在實(shí)例化的時(shí)候決定父類構(gòu)造函數(shù)的參數(shù)幢妄。
  • 如果不選擇構(gòu)造函數(shù)的那種實(shí)現(xiàn)方式兔仰,會(huì)出現(xiàn)與創(chuàng)建對(duì)象模式相同的對(duì)象識(shí)別問(wèn)題。
  • 原型鏈的改變會(huì)影響所有已經(jīng)構(gòu)造出的實(shí)例蕉鸳。這是一種靈活性乎赴,也是一種危險(xiǎn)。如果我們不小心通過(guò)實(shí)例對(duì)象改變了原型鏈上的屬性潮尝,會(huì)影響所有的實(shí)例對(duì)象无虚。
  • 父類可能有一些屬性不適合共享,但是純?cè)玩溊^承強(qiáng)迫所有父類屬性都要共享衍锚。比如People是Student的父類,People的name屬性顯然是每個(gè)子對(duì)象都應(yīng)該獨(dú)享的嗤堰。如果使用純?cè)玩溊^承戴质,我們必須在每次得到子類對(duì)象以后手動(dòng)給子對(duì)象添加name屬性度宦。

2. 純構(gòu)造函數(shù)繼承

這種技術(shù)通過(guò)在子類構(gòu)造函數(shù)中調(diào)用父類的構(gòu)造函數(shù),使所有需要繼承的屬性都定義在實(shí)例對(duì)象上告匠。

function SuperType(fatherName) {
    this.fatherName = fatherName;
    this.fatherArray = ["red", "blue", "green"];
}

function SubType(childName, fatherName) {
    SuperType.call(this, fatherName);
    this.childName = childName;
}
var child1 = new SubType('childName1', 'fatherName1');
var child2 = new SubType('childName2', 'fatherName2');

child1.fatherArray.push("black");
console.log(child1.fatherArray); //"red,blue,green,black"
console.log(child2.fatherArray); //"red,blue,green"

由上例可知戈抄,純構(gòu)造函數(shù)繼承不會(huì)出現(xiàn)純?cè)玩溊^承的問(wèn)題:

  • 不存在“原型鏈的改變影響所有已經(jīng)構(gòu)造出的實(shí)例”的問(wèn)題。這是因?yàn)椴还苁亲宇惖膶傩赃€是父類的屬性后专,在子對(duì)象上都有一個(gè)副本划鸽,因此改變一個(gè)對(duì)象的屬性不會(huì)影響另一個(gè)對(duì)象。
  • 可以在構(gòu)造子對(duì)象實(shí)例的時(shí)候給父類構(gòu)造函數(shù)傳遞參數(shù)戚哎。在純構(gòu)造函數(shù)繼承中裸诽,父類構(gòu)造函數(shù)是在子類構(gòu)造函數(shù)中調(diào)用的,每次調(diào)用時(shí)型凳,傳遞給父構(gòu)造函數(shù)的參數(shù)可以通過(guò)子構(gòu)造函數(shù)的參數(shù)控制丈冬。

純構(gòu)造函數(shù)繼承的缺陷

  • 創(chuàng)建對(duì)象的構(gòu)造函數(shù)模式相同,低效率甘畅,函數(shù)重復(fù)定義埂蕊,無(wú)法復(fù)用。
  • 如果子類要使用這種繼承方式疏唾,父類必須也要使用這種繼承方式蓄氧。因?yàn)?strong>使用這種方式的前提就是所有需要繼承的屬性都在父構(gòu)造函數(shù)上。如果父類有一些屬性是通過(guò)原型鏈繼承來(lái)的槐脏,那么子類僅僅通過(guò)調(diào)用父構(gòu)造函數(shù)無(wú)法得到這些屬性喉童。
  • 對(duì)象識(shí)別功能不全。無(wú)法使用 instanceof 來(lái)判斷某個(gè)對(duì)象是否繼承自某個(gè)父類准给。但是還是有基本的對(duì)象識(shí)別功能:可以使用 instanceof 來(lái)判斷某個(gè)對(duì)象是不是某個(gè)類的實(shí)例泄朴。

3. 組合繼承

組合繼承就是同時(shí)使用原型鏈和構(gòu)造函數(shù)繼承:

  • 對(duì)于那些適合共享的屬性(一般是函數(shù)),將它們放在原型鏈上露氮。
  • 對(duì)于需要每個(gè)子對(duì)象獨(dú)享的屬性祖灰,在構(gòu)造函數(shù)中定義。
// 定義父類
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
    console.log(this.name);
};

// 定義子類
function SubType(name, age) {
    // 這里調(diào)用了父對(duì)象的構(gòu)造函數(shù)(構(gòu)造函數(shù)繼承)
    SuperType.call(this, name);
    this.age = age;
}
// 這里創(chuàng)建了一個(gè)父對(duì)象來(lái)當(dāng)作原型(原型鏈繼承)
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
};

var instance1 = new SubType("Nicholas", 29);
var instance2 = new SubType("Greg", 27);

instance1.colors.push("black");
console.log(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29

console.log(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

使用原型鏈的時(shí)候畔规,我們要作出合理的選擇:

  • 哪些屬性是每個(gè)實(shí)例對(duì)象獨(dú)享的局扶,需要在每次實(shí)例化的時(shí)候添加到實(shí)例對(duì)象上
  • 哪些屬性是所有實(shí)例共享的叁扫,只需要定義在原型對(duì)象上三妈。這可以減少資源的浪費(fèi)。

組合繼承的代碼與純?cè)玩溊^承的代碼看起來(lái)很相似莫绣,它們的核心區(qū)別在于:組合繼承要在子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù)畴蒲。

組合繼承避免了兩者的缺陷,結(jié)合了兩者的優(yōu)點(diǎn)对室,并且可以使用instanceof進(jìn)行對(duì)象識(shí)別模燥,因此組合繼承在JavaScript中經(jīng)常被使用咖祭。

組合繼承的缺陷

  • 得到一個(gè)子對(duì)象要執(zhí)行兩次父構(gòu)造函數(shù),重復(fù)定義屬性蔫骂。在組合繼承中么翰,我們要執(zhí)行兩次構(gòu)造函數(shù)
    1. 在定義原型鏈的時(shí)候創(chuàng)建原型對(duì)象
    2. 在子類的構(gòu)造函數(shù)中調(diào)用父構(gòu)造函數(shù)來(lái)初始化新對(duì)象的屬性。

調(diào)用兩次構(gòu)造函數(shù)的結(jié)果就是重復(fù)定義了父類的屬性辽旋,第一次定義在原型鏈上浩嫌,第二次定義在子對(duì)象上。

如果你在Chrome控制臺(tái)中打印上面例子的instance2补胚,你會(huì)發(fā)現(xiàn)码耐,在原型對(duì)象和子對(duì)象上都有"name"和"colors"屬性。


這樣的重復(fù)定義顯然不夠優(yōu)雅糖儡,后面的寄生組合式繼承解決了這個(gè)問(wèn)題伐坏。

4. 原型式繼承

原型式繼承的核心是以父對(duì)象為原型直接創(chuàng)建子對(duì)象
原型式繼承(Prototypal Inheritance)是由Douglas Crockford在他的一篇文章Prototypal Inheritance in JavaScript中提出的握联。js是一種基于原型的語(yǔ)言桦沉,然而Douglas卻發(fā)現(xiàn),當(dāng)時(shí)沒(méi)有操作符能夠方便地以一個(gè)對(duì)象為原型金闽,創(chuàng)建一個(gè)新對(duì)象纯露。js的原型的天性被構(gòu)造函數(shù)給掩蓋了,因?yàn)闃?gòu)造函數(shù)被很多人當(dāng)作“類”來(lái)使用代芜。因此Douglas提出一個(gè)簡(jiǎn)單的函數(shù)埠褪,以父對(duì)象為原型直接創(chuàng)建子對(duì)象,沒(méi)有類挤庇、沒(méi)有構(gòu)造函數(shù)钞速、沒(méi)有new操作符,只有對(duì)象繼承對(duì)象嫡秕,回歸js的本質(zhì):

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

在原型式繼承被提出的時(shí)候渴语,Object.create方法還沒(méi)有引入。ES5引入的Object.create()方法實(shí)際就是object函數(shù)的規(guī)范化昆咽。

有了object函數(shù)以后驾凶,為了能夠方便地創(chuàng)建對(duì)象,你可能需要使用工廠模式掷酗,來(lái)為得到的子對(duì)象增加屬性:

// 父對(duì)象
var superObject = {
    superValue:1,
    showSuperValue: function() {
        console.log(this.superValue);
    }
};

// 子對(duì)象的工廠方法
function createSub() {
    var instance = Object.create(superObject);
    instance.subValue = 2;
    return instance;
}

var subObject = createSub();
subObject.showSuperValue();  // 1

我們有時(shí)不一定要大量制造子對(duì)象调违,此時(shí)就沒(méi)必要定義一個(gè)工廠函數(shù)了,直接使用Object.create()就好泻轰。原型式繼承不一定要定義一個(gè)工廠函數(shù)技肩,只要以父對(duì)象為原型直接創(chuàng)建子對(duì)象,就是一種原型式繼承浮声。

原型式繼承是一種純?cè)玩溊^承亩鬼,因?yàn)?strong>原型式繼承也將所有要繼承的屬性放在了原型鏈上殖告,我們?cè)诩冊(cè)玩溊^承中的第二種實(shí)現(xiàn)方式,實(shí)際上也是原型式繼承雳锋。

如果要給子對(duì)象添加函數(shù),不要在工廠函數(shù)中定義它羡洁,而要將函數(shù)放在原型對(duì)象上玷过,避免低效率代碼。我們?cè)诩冊(cè)玩溊^承中的第二種實(shí)現(xiàn)方式就是一個(gè)值得學(xué)習(xí)的例子筑煮。

5. 寄生式繼承

寄生式繼承的思想是增強(qiáng)父對(duì)象辛蚊,得到子對(duì)象。新特性“寄生”在父對(duì)象上真仲。
寄生式繼承使用工廠函數(shù)封裝了以下步驟:

  1. 使用父對(duì)象的創(chuàng)建方法(工廠函數(shù)或構(gòu)造函數(shù))袋马,創(chuàng)建父對(duì)象
  2. 增強(qiáng)父對(duì)象(給它增加屬性)
  3. 返回這個(gè)對(duì)象,它就是子對(duì)象
function Super() {
    this.superProperty = 1;
}
Super.prototype.sayHi = function() {
    console.log('hi');
};


function subFactory() {
    var instance = new Super();
    instance.subProperty = 2;
    instance.sayGoodBye = function() {
        console.log('goodbye');
    };
    return instance;
}

var sub = subFactory();

繼承得到的屬性可能在子對(duì)象上秸应,也可能在子對(duì)象的原型上虑凛,這取決于父對(duì)象的屬性在不在原型鏈上。

寄生式繼承的缺陷

  • 如果在工廠函數(shù)中為對(duì)象添加函數(shù)(如上面的例子)软啼,那么會(huì)出現(xiàn)與純構(gòu)造函數(shù)繼承一樣的低效率問(wèn)題桑谍,函數(shù)重復(fù)定義。
  • 不能使用進(jìn)行對(duì)象識(shí)別祸挪,因?yàn)樽訉?duì)象并不是通過(guò)構(gòu)造函數(shù)創(chuàng)建的锣披。

6. 寄生組合式繼承

我們前面說(shuō)過(guò),雖然組合繼承很常用贿条,但是它也有自己的不足:調(diào)用兩次父構(gòu)造函數(shù)雹仿,重復(fù)定義父屬性。第一次是在定義原型鏈的時(shí)候創(chuàng)建原型對(duì)象整以,第二次是在子類的構(gòu)造函數(shù)中調(diào)用父構(gòu)造函數(shù)來(lái)初始化新對(duì)象的屬性胧辽。以下是我們給出過(guò)的組合式繼承

// 定義父類
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
    console.log(this.name);
};

// 定義子類
function SubType(name, age) {
    // 第二次調(diào)用父構(gòu)造函數(shù)
    SuperType.call(this, name);
    this.age = age;
}
// 第一次調(diào)用父構(gòu)造函數(shù)
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
};

var instance1 = new SubType("Nicholas", 29);
var instance2 = new SubType("Greg", 27);
// instance的本身和原型對(duì)象上都有“name”和“colors”屬性

instance1.colors.push("black");
console.log(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29

console.log(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

我們顯然應(yīng)該舍棄其中的一次。
可以舍棄第二次調(diào)用嗎悄蕾?不行票顾,那樣就變成純?cè)玩溊^承了,你可以回去看看這種繼承的缺陷帆调。
既然如此奠骄,我們只能舍棄第一次調(diào)用了。第一次調(diào)用構(gòu)造函數(shù)只是為了獲得父對(duì)象原型鏈上的屬性番刊,父對(duì)象實(shí)例上的屬性交給第二次調(diào)用來(lái)添加了含鳞。實(shí)際上我們不需要?jiǎng)?chuàng)建一個(gè)父對(duì)象也可以獲得父對(duì)象的原型鏈:

也就是說(shuō),我們可以把
SubType.prototype = new SuperType();
改成
SubType.prototype = Object.create(SuperType.prototype);
創(chuàng)建上圖中的藍(lán)色空對(duì)象芹务,并將它作為子類的原型蝉绷。子對(duì)象一樣可以繼承到父對(duì)象原型鏈上的所有屬性鸭廷!

因此,寄生組合式繼承的代碼就是這樣:

// 定義父類
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
    console.log(this.name);
};

// 定義子類
function SubType(name, age) {
    // 獲得父對(duì)象實(shí)例上的屬性
    SuperType.call(this, name);
    this.age = age;
}
// 獲得父對(duì)象原型鏈上的屬性
SubType.prototype = Object.create(SuperType.prototype);
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
};

var instance1 = new SubType("Nicholas", 29);
var instance2 = new SubType("Greg", 27);

instance1.colors.push("black");
console.log(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29

console.log(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

現(xiàn)在我們?cè)贑hrome控制臺(tái)查看instance2的原型熔吗,發(fā)現(xiàn)原型鏈上已經(jīng)沒(méi)有“name”和“colors”屬性了辆床。寄生組合式繼承十分完美!

為什么不直接SubType.prototype = SuperType.prototype;呢桅狠?因?yàn)槲覀兒竺孢€要在SubType.prototype上添加子對(duì)象的共享函數(shù)讼载,如果使用Object.create創(chuàng)建一個(gè)新對(duì)象,會(huì)改變父對(duì)象的原型鏈中跌!


寄生組合式繼承真的與“寄生式繼承”有關(guān)嗎咨堤?對(duì)于這一點(diǎn)我持懷疑態(tài)度。按照《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》的說(shuō)法漩符,因?yàn)槔^承的過(guò)程可以封裝成以下函數(shù):

function inheritPrototype(subType, superType) {
    var prototype = Object.create(superType.prototype); // 創(chuàng)建對(duì)象
    prototype.constructor = subType; // 增強(qiáng)對(duì)象
    subType.prototype = prototype; // 指定對(duì)象
}

而作者認(rèn)為這個(gè)函數(shù)是一種“寄生式繼承”:prototype“寄生式繼承”自superType.prototype一喘。

我認(rèn)為這是一種原型式繼承。不能因?yàn)樵诠S函數(shù)中獲取對(duì)象嗜暴、增強(qiáng)對(duì)象凸克,就認(rèn)為它是寄生式繼承。原型式繼承一樣可以用工廠函數(shù)來(lái)封裝灼伤。原型式繼承與寄生式繼承的區(qū)別在于獲取對(duì)象的方式

  • 通過(guò)object函數(shù)或Object.create触徐,以父對(duì)象為原型直接創(chuàng)建一個(gè)空對(duì)象。這是原型式繼承狐赡。
  • 通過(guò)父類的構(gòu)造函數(shù)或工廠函數(shù)獲得對(duì)象撞鹉。這是寄生式繼承。

在Douglas Crockford的文章Prototypal Inheritance in JavaScript中颖侄,在介紹原型式繼承的時(shí)候他說(shuō)到:
"For convenience, we can create functions which will call the object function for us, and provide other customizations such as augmenting the new objects with privileged functions. I sometimes call these maker functions. If we have a maker function that calls another maker function instead of calling the object function, then we have a parasitic inheritance pattern."
原型式繼承一樣可以使用工廠函數(shù)鸟雏。當(dāng)調(diào)用另一個(gè)工廠函數(shù)而不是object函數(shù)的時(shí)候,原型式繼承才變成寄生式繼承览祖。

名字叫什么并不重要孝鹊,能夠?qū)⑦@些模式中的編程思想融會(huì)貫通就夠了。將來(lái)我們不一定有機(jī)會(huì)寫(xiě)“形式完全規(guī)范”的某種模式展蒂,但是其中的思想肯定會(huì)在一些零零散散的地方用上又活。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锰悼,隨后出現(xiàn)的幾起案子柳骄,更是在濱河造成了極大的恐慌,老刑警劉巖箕般,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耐薯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)曲初,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門体谒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人臼婆,你說(shuō)我怎么就攤上這事抒痒。” “怎么了颁褂?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵评汰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我痢虹,道長(zhǎng),這世上最難降的妖魔是什么主儡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任奖唯,我火速辦了婚禮,結(jié)果婚禮上糜值,老公的妹妹穿的比我還像新娘丰捷。我一直安慰自己,他們只是感情好寂汇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布病往。 她就那樣靜靜地躺著,像睡著了一般骄瓣。 火紅的嫁衣襯著肌膚如雪停巷。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天榕栏,我揣著相機(jī)與錄音畔勤,去河邊找鬼。 笑死扒磁,一個(gè)胖子當(dāng)著我的面吹牛庆揪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妨托,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缸榛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了兰伤?” 一聲冷哼從身側(cè)響起内颗,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎医清,沒(méi)想到半個(gè)月后起暮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年负懦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了筒捺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纸厉,死狀恐怖系吭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颗品,我是刑警寧澤肯尺,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站躯枢,受9級(jí)特大地震影響则吟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锄蹂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一氓仲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧得糜,春花似錦敬扛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至治宣,卻和暖如春急侥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背炼七。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工缆巧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豌拙。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓陕悬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親按傅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捉超,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 1、構(gòu)造函數(shù)模式 [url=]file:///C:/Users/i037145/AppData/Local/Tem...
    橫沖直撞666閱讀 843評(píng)論 0 0
  • 基于這篇文章的一些名稱約定: 上面的約定應(yīng)該是比較合理的唯绍,如果難以理解拼岳,可以查看黯羽輕揚(yáng):JS學(xué)習(xí)筆記2_面向?qū)ο?..
    一直玩編程閱讀 520評(píng)論 1 7
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,401評(píng)論 3 12
  • 本章內(nèi)容 理解對(duì)象屬性 理解并創(chuàng)建對(duì)象 理解繼承 面向?qū)ο笳Z(yǔ)言有一個(gè)標(biāo)志,那就是它們都有類的概念况芒,而通過(guò)類可以創(chuàng)建...
    悶油瓶小張閱讀 841評(píng)論 0 1
  • 這些年過(guò)得不好不壞 我已還清了所有的債 已開(kāi)始試著慢慢攢錢 每個(gè)月都會(huì)和朋友見(jiàn)見(jiàn)面 吹吹牛惜纸,侃侃大山 我有時(shí)還是會(huì)...
    我是阿麥閱讀 209評(píng)論 0 2