javascript基礎(chǔ)知識問答——原型和原型鏈

  • 1.理解原型設(shè)計(jì)模式以及JavaScript中的原型規(guī)則
  • 2.instanceof的底層實(shí)現(xiàn)原理,手動實(shí)現(xiàn)一個(gè)instanceof
  • 3.實(shí)現(xiàn)繼承的幾種方式以及他們的優(yōu)缺點(diǎn)
  • 4.至少說出一種開源項(xiàng)目(如Node)中應(yīng)用原型繼承的案例
  • 5.可以描述new一個(gè)對象的詳細(xì)過程泡态,手動實(shí)現(xiàn)一個(gè)new操作符
  • 6.理解es6 class構(gòu)造以及繼承的底層實(shí)現(xiàn)原理

一. 理解原型設(shè)計(jì)模式以及javascript中的原則規(guī)則

原型設(shè)計(jì)模式栈暇,這種設(shè)計(jì)模式就是創(chuàng)建一個(gè)共享的原型块差,并通過拷貝這些原型創(chuàng)建新的對象。用于創(chuàng)建重復(fù)的對象,這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式弓乙,它提供了一種創(chuàng)建對象的不錯選擇【澹可以通過原型鏈實(shí)現(xiàn)原型設(shè)計(jì)模式暇韧。
原型設(shè)計(jì)模式主要的特性

  • 所有函數(shù)(類)以及部分?jǐn)?shù)據(jù)類型(number數(shù)值型、string字符串型浓瞪、array數(shù)組型懈玻、function函數(shù)型)具有prototype屬性;
  • 在prototype屬性上設(shè)置的屬性乾颁,所有的實(shí)例均可以共享涂乌;
  • 在實(shí)例上可修改prototype屬性上設(shè)置的屬性
    • 值類型修改:僅限當(dāng)前實(shí)例發(fā)生變更
    • 引用類型修改:
      • 直接修改引用類型艺栈,只影響當(dāng)前實(shí)例的值,并且在修改后湾盒,引用地址發(fā)生變化湿右,后續(xù)對該實(shí)例上所有屬性更改只對當(dāng)前實(shí)例起作用
      • 修改應(yīng)用類型的屬性或者項(xiàng),父類就會發(fā)生更改罚勾,故會影響到所有實(shí)例的值
  • 類可以直接設(shè)置靜態(tài)屬性毅人,可以只用通過 ' 類名.屬性名 = 值 ' 來設(shè)置和訪問,但實(shí)例不可訪問尖殃;
var person = {
    name: 'zhangsan',
    age: 25,
    sayHello: function(){
        return this.name
    }
}//先構(gòu)建一個(gè)類

var man = Object.create(person,{
    job: {
        value: 'IT'
    }
});//利用Object.create(prototype, optionalDescriptorObjects)來使用現(xiàn)有的對象來提供新創(chuàng)建的對象的__proto__
console.log(man.sayHello())  // zhangsan
console.log(man.age) // 25
console.log(man.job)  // IT
console.log(man.__proto__ === prototype)  //true

可以看到丈莺,我們通過Object.create()創(chuàng)建對象,此時(shí)新建的對象就繼承自構(gòu)造器的原型對象送丰,及繼承了初始的person场刑,而且可以查看返回值的proto屬性和person內(nèi)的prototype是一樣的。我們常說一個(gè)對象的原型蚪战,實(shí)際上我們是在說這個(gè)對象的構(gòu)造器是有原型的牵现。我們通過該方式,創(chuàng)建了一個(gè)新的對象邀桑,并且繼承了自構(gòu)造器的屬性瞎疼,這就是原型設(shè)計(jì)模式。
在JavaScript中壁畸,對象可以使用原型克隆來實(shí)現(xiàn)獲取以及繼承原型對象的屬性和方法贼急,很多情況下開發(fā)者會使用原型對象的Object.prototype,但是今天我們介紹了也可以通過Object.create()方法實(shí)現(xiàn)對我們需要的目標(biāo)對象為原型的克隆操作捏萍,同時(shí)也可以通過修改構(gòu)造器的prototype指向來復(fù)制其它對象的屬性及方法

原型中的一些規(guī)則:

  1. 所有的引用數(shù)據(jù)類型(array數(shù)組類型太抓,object對象類型,function函數(shù)類型)都具有自由擴(kuò)展的屬性令杈;
  2. 所有的引用數(shù)據(jù)類型都有一個(gè)proto屬性即隱式原型走敌,其屬性值是一個(gè)普通對象;
  3. 所有的函數(shù)逗噩,都具有一個(gè)prototype即顯式原型掉丽,其屬性值也是一個(gè)普通對象;
  4. 所有的引用數(shù)據(jù)類型异雁,它的隱式原型(proto)都是指向其構(gòu)造函數(shù)的顯示原型(prototype)捶障,即(obj.proto === Object.prototype);
  5. 如果想獲取或利用某個(gè)對象的屬性或方法時(shí)纲刀,這個(gè)對象本身沒有這個(gè)屬性或防范项炼,那么我們可以去它的proto即它指向的構(gòu)造函數(shù)的prototype上去查找;

二. instanceof的底層實(shí)現(xiàn)原理,手動實(shí)現(xiàn)一個(gè)instanceof

查看某對象的prototype屬性指向的原型對象是否在另一對象的原型鏈上锭部,如果在就返回true暂论,如果不在返回false

123 instanceof Number, //false
'dsfsf' instanceof String, //false
false instanceof Boolean, //false
[1, 2, 3] instanceof Array, //true
{a: 1} instanceof Object, //true
function () {} instanceof Function, //true
undefined instanceof Object, //false
null instanceof Object, //false
new Date() instanceof Date, //true
/^[a-zA-Z]{5,20}$/ instanceof RegExp, //true
new Error() instanceof Error //true

三. 實(shí)現(xiàn)繼承的幾種方式以及他們的優(yōu)缺點(diǎn)

首先,得有一個(gè)父類

// 定義一個(gè)動物類
function Animal (name) {
  // 屬性
  this.name = name || 'Animal';
  // 實(shí)例方法
  this.sleep = function(){
    console.log(this.name + '正在睡覺空免!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
  1. 原型鏈的繼承
    核心: 將父類的實(shí)例作為子類的原型
function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

特點(diǎn):

  1. 非常純粹的繼承關(guān)系空另,實(shí)例是子類的實(shí)例,也是父類的實(shí)例
  2. 父類新增原型方法/原型屬性蹋砚,子類都能訪問到
  3. 簡單扼菠,易于實(shí)現(xiàn)
    缺點(diǎn):
  • 要想為子類新增屬性和方法,必須要在new Animal()這樣的語句之后執(zhí)行坝咐,不能放到構(gòu)造器中
  • 無法實(shí)現(xiàn)多繼承
  • 來自原型對象的所有屬性被所有實(shí)例共享
  • 創(chuàng)建子類實(shí)例時(shí)循榆,無法向父類構(gòu)造函數(shù)傳參
  1. 構(gòu)造函數(shù)
    核心:使用父類的構(gòu)造函數(shù)來增強(qiáng)子類實(shí)例,等于是復(fù)制父類的實(shí)例屬性給子類(沒用到原型)
function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

特點(diǎn):

  • 解決了1中墨坚,子類實(shí)例共享父類引用屬性的問題
  • 創(chuàng)建子類實(shí)例時(shí)秧饮,可以向父類傳遞參數(shù)
  • 可以實(shí)現(xiàn)多繼承(call多個(gè)父類對象)

缺點(diǎn):

  • 實(shí)例并不是父類的實(shí)例,只是子類的實(shí)例
  • 只能繼承父類的實(shí)例屬性和方法泽篮,不能繼承原型屬性/方法
  • 無法實(shí)現(xiàn)函數(shù)復(fù)用盗尸,每個(gè)子類都有父類實(shí)例函數(shù)的副本,影響性能
  1. 實(shí)例繼承
    核心:為父類實(shí)例添加新特性帽撑,作為子類實(shí)例返回
function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

特點(diǎn):

  • 不限制調(diào)用方式泼各,不管是new 子類()還是子類(),返回的對象具有相同的效果

缺點(diǎn):

  • 實(shí)例是父類的實(shí)例,不是子類的實(shí)例
  • 不支持多繼承
  1. 拷貝繼承
function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  Cat.prototype.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

特點(diǎn):

  • 支持多繼承

缺點(diǎn):

  • 效率較低亏拉,內(nèi)存占用高(因?yàn)橐截惛割惖膶傩裕?/li>
  • 無法獲取父類不可枚舉的方法(不可枚舉方法扣蜻,不能使用for in 訪問到)
  1. 組合繼承
    核心:通過調(diào)用父類構(gòu)造,繼承父類的屬性并保留傳參的優(yōu)點(diǎn)及塘,然后通過將父類實(shí)例作為子類原型莽使,實(shí)現(xiàn)函數(shù)復(fù)用
function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();// 組合繼承也需要修復(fù)構(gòu)造函數(shù)指向
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

特點(diǎn):
* 彌補(bǔ)了方式2的缺陷,可以繼承實(shí)例屬性/方法笙僚,也可以繼承原型屬性/方法
既是子類的實(shí)例芳肌,也是父類的實(shí)例
* 不存在引用屬性共享問題
* 可傳參
* 函數(shù)可復(fù)用

缺點(diǎn):
* 調(diào)用了兩次父類構(gòu)造函數(shù),生成了兩份實(shí)例(子類實(shí)例將子類原型上的那份屏蔽了)

  1. 寄生組合繼承
    核心:通過寄生方式味咳,砍掉父類的實(shí)例屬性庇勃,這樣,在調(diào)用兩次父類的構(gòu)造的時(shí)候槽驶,就不會初始化兩次實(shí)例方法/屬性,避免的組合繼承的缺點(diǎn)
function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){
  // 創(chuàng)建一個(gè)沒有實(shí)例方法的類
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //將實(shí)例作為子類的原型
  Cat.prototype = new Super();
})();

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true感謝 @bluedrink 提醒鸳兽,該實(shí)現(xiàn)沒有修復(fù)constructor掂铐。Cat.prototype.constructor = Cat; // 需要修復(fù)下構(gòu)造函數(shù)

特點(diǎn):堪稱完美
缺點(diǎn):實(shí)現(xiàn)較為復(fù)雜

四. 至少說出一種開源項(xiàng)目(如Node)中應(yīng)用原型繼承的案例

五. 可以描述new一個(gè)對象的詳細(xì)過程,手動實(shí)現(xiàn)一個(gè)new操作符

1、創(chuàng)建一個(gè)新的對象
2全陨、把obj的proto指向fn的prototype,實(shí)現(xiàn)繼承
3爆班、改變this的指向,執(zhí)行構(gòu)造函數(shù)辱姨、傳遞參數(shù),fn.apply(obj,) 或者 fn.call()
4柿菩、返回新的對象obj

  function Dog(name) {
        this.name = name
        this.say = function () {
            console.log('name = ' + this.name)
        }
    }
    function Cat(name) {
        this.name = name
        this.say = function () {
            console.log('name = ' + this.name)
        }
    }
    function _new(fn, ...arg) {
        const obj = {}; //創(chuàng)建一個(gè)新的對象
        obj.__proto__ = fn.prototype; //把obj的__proto__指向fn的prototype,實(shí)現(xiàn)繼承
        fn.apply(obj, arg) //改變this的指向
        return Object.prototype.toString.call(obj) == '[object Object]'? obj : {} //返回新的對象obj
    }
 
    //測試1
    var dog = _new(Dog,'aaa')
    dog.say() //'name = aaa'
    console.log(dog instanceof Dog) //true
    console.log(dog instanceof Cat) //true
    //測試2
    var cat = _new(Cat, 'bbb'); 
    cat.say() //'name = bbb'

六. 理解es6 class構(gòu)造以及繼承的底層實(shí)現(xiàn)原理

javascript使用的是原型式繼承,我們可以通過原型的特性實(shí)現(xiàn)類的繼承雨涛,
es6為我們提供了像面向?qū)ο罄^承一樣的語法糖枢舶。

class Parent {
  constructor(a){
    this.filed1 = a;
  }
  filed2 = 2;
  func1 = function(){}
}

class Child extends Parent {
    constructor(a,b) {
      super(a);
      this.filed3 = b;
    }
  
  filed4 = 1;
  func2 = function(){}
}

下面我們借助babel來探究es6類和繼承的實(shí)現(xiàn)原理。

1. 類的實(shí)現(xiàn)

轉(zhuǎn)換前

class Parent {
  constructor(a){
    this.filed1 = a;
  }
  filed2 = 2;
  func1 = function(){}
}

轉(zhuǎn)換后:

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Parent = function Parent(a) {
  _classCallCheck(this, Parent);
  this.filed2 = 2;
  this.func1 = function () { };
  this.filed1 = a;
};

可見class的底層依然是構(gòu)造函數(shù):
1.調(diào)用_classCallCheck方法判斷當(dāng)前函數(shù)調(diào)用前是否有new關(guān)鍵字替久。

構(gòu)造函數(shù)執(zhí)行前有new關(guān)鍵字凉泄,會在構(gòu)造函數(shù)內(nèi)部創(chuàng)建一個(gè)空對象,將構(gòu)造函數(shù)的proptype指向這個(gè)空對象的proto,并將this指向這個(gè)空對象蚯根。如上后众,_classCallCheck中:this instanceof Parent 返回true。

若構(gòu)造函數(shù)前面沒有new則構(gòu)造函數(shù)的proptype不會不出現(xiàn)在this的原型鏈上颅拦,返回false蒂誉。

2.將class內(nèi)部的變量和函數(shù)賦給this。
3.執(zhí)行constuctor內(nèi)部的邏輯距帅。
4.return this (構(gòu)造函數(shù)默認(rèn)在最后我們做了)右锨。

2. 繼承實(shí)現(xiàn)

轉(zhuǎn)換前:

class Child extends Parent {
    constructor(a,b) {
      super(a);
      this.filed3 = b;
    }
  
  filed4 = 1;
  func2 = function(){}
}

轉(zhuǎn)換后:
我們先看Child內(nèi)部的實(shí)現(xiàn),再看內(nèi)部調(diào)用的函數(shù)是怎么實(shí)現(xiàn)的:

var Child = function (_Parent) {
  _inherits(Child, _Parent);
  function Child(a, b) {
    _classCallCheck(this, Child);
    var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, a));
    _this.filed4 = 1;
    _this.func2 = function () {};
    _this.filed3 = b;
    return _this;
  }
  return Child;
}(Parent);
1.調(diào)用_inherits函數(shù)繼承父類的proptype锥债。

_inherits內(nèi)部實(shí)現(xiàn):

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { value: subClass, enumerable: false, writable: true, configurable: true }
  });
  if (superClass)
    Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

(1) 校驗(yàn)父構(gòu)造函數(shù)陡蝇。
(2) 典型的寄生繼承:用父類構(gòu)造函數(shù)的proptype創(chuàng)建一個(gè)空對象,并將這個(gè)對象指向子類構(gòu)造函數(shù)的proptype哮肚。
(3) 將父構(gòu)造函數(shù)指向子構(gòu)造函數(shù)的proto(這步是做什么的不太明確登夫,感覺沒什么意義。)

2.用一個(gè)閉包保存父類引用允趟,在閉包內(nèi)部做子類構(gòu)造邏輯恼策。
3.new檢查。
4.用當(dāng)前this調(diào)用父類構(gòu)造函數(shù)
var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, a));

這里的Child.proto || Object.getPrototypeOf(Child)實(shí)際上是父構(gòu)造函數(shù)(_inherits最后的操作)潮剪,然后通過call將其調(diào)用方改為當(dāng)前this涣楷,并傳遞參數(shù)。(這里感覺可以直接用參數(shù)傳過來的Parent)

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }
  return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

校驗(yàn)this是否被初始化抗碰,super是否調(diào)用狮斗,并返回父類已經(jīng)賦值完的this。

5.將行子類class內(nèi)部的變量和函數(shù)賦給this弧蝇。
6.執(zhí)行子類constuctor內(nèi)部的邏輯碳褒。

可見折砸,es6實(shí)際上是為我們提供了一個(gè)“組合寄生繼承”的簡單寫法。

3. super

super代表父類構(gòu)造函數(shù)沙峻。
super.fun1() 等同于 Parent.fun1() 或 Parent.prototype.fun1()睦授。
super() 等同于Parent.prototype.construtor()

當(dāng)我們沒有寫子類構(gòu)造函數(shù)時(shí):

var Child = function (_Parent) {
  _inherits(Child, _Parent);

  function Child() {
    _classCallCheck(this, Child);

    return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments));
  }
  return Child;
}(Parent);

可見默認(rèn)的構(gòu)造函數(shù)中會主動調(diào)用父類構(gòu)造函數(shù),并默認(rèn)把當(dāng)前constructor傳遞的參數(shù)傳給了父類摔寨。
所以當(dāng)我們聲明了constructor后必須主動調(diào)用super(),否則無法調(diào)用父構(gòu)造函數(shù)去枷,無法完成繼承。
典型的例子就是Reatc的Component中是复,我們聲明constructor后必須調(diào)用super(props)删顶,因?yàn)楦割愐跇?gòu)造函數(shù)中對props做一些初始化操作。

參考鏈接:https://blog.csdn.net/Kreme/java/article/details/102940455
https://blog.csdn.net/Kreme/java/article/details/102975973
https://www.cnblogs.com/humin/p/4556820.html
https://blog.csdn.net/qq_39985511/java/article/details/87692673
https://blog.csdn.net/qq_34149805/java/article/details/86105123

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佑笋,一起剝皮案震驚了整個(gè)濱河市翼闹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒋纬,老刑警劉巖猎荠,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜀备,居然都是意外死亡关摇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門碾阁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來输虱,“玉大人,你說我怎么就攤上這事脂凶∠芏茫” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵蚕钦,是天一觀的道長亭病。 經(jīng)常有香客問我,道長嘶居,這世上最難降的妖魔是什么罪帖? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮邮屁,結(jié)果婚禮上整袁,老公的妹妹穿的比我還像新娘。我一直安慰自己佑吝,他們只是感情好坐昙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芋忿,像睡著了一般民珍。 火紅的嫁衣襯著肌膚如雪襟士。 梳的紋絲不亂的頭發(fā)上盗飒,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天嚷量,我揣著相機(jī)與錄音,去河邊找鬼逆趣。 笑死蝶溶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宣渗。 我是一名探鬼主播抖所,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痕囱!你這毒婦竟也來了田轧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鞍恢,失蹤者是張志新(化名)和其女友劉穎傻粘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帮掉,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弦悉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蟆炊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稽莉。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖涩搓,靈堂內(nèi)的尸體忽然破棺而出污秆,到底是詐尸還是另有隱情,我是刑警寧澤昧甘,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布良拼,位于F島的核電站,受9級特大地震影響疾层,放射性物質(zhì)發(fā)生泄漏将饺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一痛黎、第九天 我趴在偏房一處隱蔽的房頂上張望予弧。 院中可真熱鬧,春花似錦湖饱、人聲如沸掖蛤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚓庭。三九已至致讥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間器赞,已是汗流浹背垢袱。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留港柜,地道東北人请契。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像夏醉,于是被迫代替她去往敵國和親爽锥。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345