JS的構(gòu)造函數(shù),原型繼承匠题,Class

1.構(gòu)造函數(shù) constructor

使用構(gòu)造函數(shù)就可以實現(xiàn)代碼的復(fù)用拯坟,創(chuàng)建具有相似的特征(屬性)和行為(方法)的對象。
構(gòu)造函數(shù)必須通過關(guān)鍵字new調(diào)用韭山,會創(chuàng)建一個新的內(nèi)存空間郁季,函數(shù)體內(nèi)部的 this 指向該內(nèi)存。構(gòu)造函數(shù)的最后一步默認(rèn)(隱式)返回this钱磅,如果手動添加返回值梦裂,若為基本數(shù)據(jù)類型則依然為this,如為引用類型(對象/數(shù)組)則返回該引用盖淡。

function Person(age) {
    this.age = age;
    return age
}
var p = new Person(18);//{age:18}
console.log(p.constructor);//function Person

2.原型鏈

每個對象具有內(nèi)部原型__proto__年柠,每個函數(shù)具有構(gòu)造器原型prototype

讀取對象屬性時褪迟,如屬性不存在冗恨,則會在其__proto__上尋找,如還不存在則繼續(xù)往上一級尋找味赃。

函數(shù)默認(rèn)的prototype是一個對象掀抹,它僅有constructor屬性,并指向該函數(shù)自身心俗。因此其實例對象也會繼承該constructor屬性(詳見下文 2.4 構(gòu)造函數(shù))傲武。

obj.__proto__ === obj.constructor.prototype === Fn.prototype

既然Fn.prototype是一個對象,顯然對象的構(gòu)造函數(shù)為Object另凌,因此有:

Fn.prototype.__proto__ === Object.prototype

除了直接讀取或?qū)懭?code>__proto__谱轨、prototype外,也可以使用以下方法:Object.setPrototypeOf()(寫操作)吠谢、Object.getPrototypeOf()(讀操作)土童、Object.create()(生成操作)。

//以下均為===(全等)關(guān)系
new Person().__proto__ 
=== Person.prototype 
=== Object.getPropertyOf(new Person())

console.log(Person.prototype); // {constructor:function Person(){}}
console.log(p.prototype); // undefined

函數(shù)也是對象的一種工坊。對于函數(shù)作為對象來說献汗,上面的規(guī)則同樣適用敢订,函數(shù)對象都是由Function函數(shù)生成的:

function fn(){}
fn.__proto__ === Function.prototype;//true
Function.__proto__ === Function.prototype;//true
Object.__proto__ === Function.prototype;//true
2.1 原型可以共享屬性和方法

原型鏈上的屬性會被實例所繼承,且為全等關(guān)系罢吃。這是原型鏈最大的作用楚午。

function Person() {}
Person.prototype.arr = [0,1,2];
var p1 = new Person() , p2 = new Person();
p1.arr === p2.arr;//true

function Animal(){
  this.arr = [0,1,2];
}
var a1 = new Animal() , a2 = new Animal();
a1.arr === a2.arr;//false

實例中繼承的引用類型修改會導(dǎo)致整個原型鏈的變動。

p1.arr.push(3);
p2.arr//[0,1,2,3]
2.2 判斷屬性類型
  • hasOwnProperty()
    用于判斷屬性是否是實例屬性尿招。true說明是實例屬性矾柜,false說明不是實例屬性。
  • in
    對象能夠訪問給定屬性時返回true,無論該屬性存在于實例中還是原型中就谜。
    • for ... in ...遍歷同樣不會區(qū)分實例屬性和原型屬性
2.3 instanceof 和 typeof
  • obj instanceof Object 檢測Object.prototype是否存在于obj的原型鏈上怪蔑。
    • null instanceof null會報錯:Right-hand side of 'instanceof' is not an object
  • typeof XXX 返回XXX類型的字符串,可以為"number", "string", "object", "boolean", "function", "undefined", "symbol"
    • type of null會返回"object"
  • 直接使用Object.prototype.toString.call(XXX)可以得到比較滿意的結(jié)果
Object.prototype.toString.call('hi') // "[object String]"
function Person() {
    this.age = 20;
};
var a = Person;
function Student() { };
Student.prototype = new Person();//繼承原型
var s = new Student();

console.log(Person instanceof Function);//true
//s.__proto__===Student.prototype===new Person()
//new Person.__proto__=== Person.prototype
console.log(s.__proto__.__proto__ === Person.prototype);//true
console.log(s instanceof Person);//true
console.log(s.__proto__ === Student.prototype);//true
console.log(s instanceof Student);//true

2.4 constructor

constructor存在于每一個函數(shù)的 prototype 中丧荐,指向函數(shù)自身缆瓣。

//以下均為===(全等)關(guān)系
    Person
    Person.prototype.constructor
    p.constructor
    p.__proto__.constructor

 //function Function(){} 每個函數(shù)都是通過new Function()構(gòu)造的,包括構(gòu)造函數(shù)
    console.log(Person.constructor);
    console.log(Function.constructor);
    console.log(Object.constructor);

// function Object(){} 每個對象都是通過new Object()構(gòu)造的
    console.log({}.constructor); 

 //function Array(){} 每個數(shù)組都是通過new Array()構(gòu)造的
    console.log([].constructor); 
2.5 特例 Function 與 Object
  • Object的prototype也是一個類型為"object"的對象虹统,但比一般函數(shù)的默認(rèn)prototype多了一大堆方法弓坞,這些方法都是JavaScript對象的系統(tǒng)默認(rèn)方法。
    Object.prototype.__proto__ === null车荔,這就是JavaScript原型鏈的終點渡冻。(否則若按照通用規(guī)則Object.prototype.__proto__ === Object.prototype會造成無限遞歸)
  • Function
    不同于type of 一般函數(shù).prototype === 'object',為一個包含constructor的對象夸赫,type of Function.prototype === 'function'菩帝。

規(guī)定Function.prototype.__proto__ === Object.prototype(這是因為如果按照通用規(guī)則Function.prototype.__proto__ === Function.prototype會造成無限遞歸茬腿,且可以讓__proto__構(gòu)成的原型鏈指向了唯一的終點:Object.prototype.__proto__ === null)

console.log(typeof Function.prototype);// "function"
console.log(Function.prototype);// ? () { [native code] } 系統(tǒng)編譯好的二進(jìn)制代碼
  • Function instanceof Object //true
    Function.__proto__ == Function.prototype => Function.prototype.__proto__ == Object.prototype
  • Object instanceof Object //true
    Object.__proto__ == Function.prototype => Function.prototype.__proto__ == Object.prototype
  • Function instanceof Function //true
    Function.__proto__ == Function.prototype
  • Object instanceof Function //true
    Object.__proto__ == Function.prototype
2.6 復(fù)寫原型 & 原型鏈繼承

原型和實例是動態(tài)關(guān)聯(lián)的呼奢,因此先生成實例再修改原型俺泣,實例依然可以繼承修改結(jié)果固额。
當(dāng)原型被復(fù)寫(本質(zhì)上只是prototype指向一個新的對象,原原型對象依然存在)扫尖,原有實例依然繼承原原型悴品,新實例繼承新原型禀综。此時constructor也為新原型的constructor。

function Animal(){}
var dog = new Animal();
Animal.prototype.age = 18;
console.log(dog.age,dog.constructor);//18 Animal

//通過原型繼承,peter可以拿到Human中的實例屬性,以及Animal和Animal.prototype中的原型屬性
function Human(){}
Human.prototype = new Animal();
var peter = new Human();
console.log(peter.age,peter.constructor);//18 Animal

Animal.prototype = {};
var cat = new Animal();
console.log(dog.age,dog.constructor);//18 Animal
console.log(peter.age,peter.constructor);//18 Animal
console.log(cat.age,cat.constructor);//undefined Object

Animal.prototype = {constructor:Animal};
var duck = new Animal();
console.log(duck.age,duck.constructor);//undefined Animal
  • 缺點 :
    2.1 中所說苔严,原型對象上引用類型的值可以通過實例進(jìn)行修改定枷,致使所有實例的該引用類型值隨之改變,這是原型鏈繼承的弊端之一届氢。另一弊端是無法通過子類向父類中傳參欠窒。
2.7 借用構(gòu)造函數(shù)繼承

借用構(gòu)造函數(shù)繼承,是在子類的構(gòu)造函數(shù)中通過 apply ()call () 調(diào)用父類構(gòu)造函數(shù)退子,以實現(xiàn)繼承岖妄。

function Animal(age) {
    this.age = age;
    this.friends = ["A"]
}
Animal.prototype.shout = "wowow";
function Human({name, age}) {
    this.name = name;
    Animal.call(this, age);
}
var peter = new Human({name:"peter", age:18});
peter.friends.push("B");
var tom = new Human({name:"tom", age:22});
console.log(peter.shout);//undefined
console.log(peter.name, peter.age, peter.friends, peter.constructor);//peter 18 [A,B] Human
console.log(tom.name, tom.age, tom.friends, tom.constructor);//tom 22 [A] Human
  • 缺點:
    這種形式的繼承型将,每個子類實例都會拷貝一份父類構(gòu)造函數(shù)中的方法,作為實例自己的方法荐虐,因此每個引用類型也是獨立的而非指針七兜,不會相互影響。但相對的福扬,占用內(nèi)存大腕铸,復(fù)用性差,且實例一旦生成就和父類無關(guān)忧换,父類的修改只能影響到修改之后生成的實例恬惯。
2.8 組合繼承

將兩者結(jié)合到一起

  • 將引用類型 / 待傳參的方法放到父類中,通過.call進(jìn)行拷貝,獲取獨立內(nèi)存,不會相互影響
  • 將基本類型 / 無參數(shù)方法放到父類的原型鏈上,將父類的實例作為子類的原型,并最終通過原型鏈繼承給實例,占用內(nèi)存小
function Animal(age) {
    if (age) this.age = age;
    this.friends = ["A"]
}
Animal.prototype.shout = "wowow";
function Human(name, age) {
    this.name = name;
    Animal.call(this, age);
}
Human.prototype = new Animal(5);//繼承父類原型
Human.prototype.constructor  = Human;//讓子類原型對象的`constructor`屬性指向子類自身,因為在上一步中亚茬,`constructor`屬性被覆蓋為父類的構(gòu)造函數(shù)
var peter = new Human("peter", 18);
peter.friends.push("B");
var tom = new Human("tom");
console.log(peter.shout);//wowow
console.log(peter.name, peter.age, peter.friends, peter.constructor);//peter 18 Human [A,B]
console.log(tom.name, tom.age, tom.friends, tom.constructor);//tom 5 Human [A]
console.log(peter instanceof Human);//true
console.log(peter instanceof Animal);//true

3.Class

ES6引入了Class(類)這個概念,通過class關(guān)鍵字可以定義類浓恳,使得語法上更類似面向?qū)ο笳Z言刹缝。但本質(zhì)上類就是一個構(gòu)造函數(shù),因此其各方面性質(zhì)和構(gòu)造函數(shù)相同颈将。
class不存在變量提升梢夯,所以需要先定義再使用
類中默認(rèn)為嚴(yán)格模式,其this不會指向window

3.0 類的定義及成員
class A {};
var B = class {};
var C = class D {
  log() {
    console.log(D.prototype == this.__proto__);
  }
}
new C().log();//true

需要注意的是晴圾,這個類的名字是C而不是D颂砸,D只在Class的內(nèi)部代碼可用,指代當(dāng)前類死姚。

  • constructor

    • 此構(gòu)造方法非彼構(gòu)造方法人乓,不是Person.constructor
    • 如沒有顯式定義都毒,會隱式生成一個constructor方法色罚。
    • constructor方法默認(rèn)(隱式)返回實例對象this,也可以手動添加對象/數(shù)組作為返回值账劲。
  • 實例成員
    constructor 中通過 this 聲明的成員都稱為實例成員戳护,只能通過實例訪問
    ES7(ES2016)起類中聲明的不加static的成員都視為實例成員

  • 原型成員(在ES7(ES2016)中廢棄
    一種特殊的成員,僅在ES6中存在瀑焦,在類中聲明但不加static腌且,既不是實例屬性,也不是靜態(tài)屬性榛瓮。
    原型成員定義在class的prototype上铺董,可同時被類和實例訪問(類似python)。

    • 屬性和方法可直接被類調(diào)用榆芦,可以通過繼承被實例調(diào)用
    • 方法不需要使用 function 關(guān)鍵字柄粹,且不使用逗號分隔
    • 由于引用類型的值不會出現(xiàn)在原型屬性上喘鸟,避免了原型鏈繼承的實例引用值修改影響原型鏈問題
class Person{//定義了一個名字為Person的類
    value = 600;
    constructor(name,age){//構(gòu)造方法,用來接收參數(shù)
        this.name = name;//this代表的是實例對象
        this.age = age;
        this.showAge= function(){
             console.log(this.age);
        }
    }
    say(){//這是一個類的方法驻右,注意千萬不要加上function
        return "我的名字叫" + this.name+"今年"+this.age+"歲了";
    }
}
var obj=new Person("laotie",18);
console.log(obj.say());//我的名字叫l(wèi)aotie今年18歲了
console.log(obj.value);//600
obj.showAge();//18
console.log(Person.constructor);//Function
console.log(Person.prototype.constructor);//Person

Person.prototype.say = function(){
  return "我被復(fù)寫了"
};
console.log(obj.say());//我被復(fù)寫了

類的本質(zhì)是將非方法屬性添加到實例什黑,將方法添加到原型
以下類A和構(gòu)造函數(shù)B等價:

class A {
    age = 18
    fn() {
        console.log(this.age)
    }

}

let a = new A()
console.log(a) //{age:18}
console.log(a.__proto__, a.__proto__ === A.prototype) //{constructor:  A, fn: ?} , true


function B() {
    this.age = 18
}
B.prototype.fn = function() {
    console.log(this.age)
}

let b = new B()
console.log(b) //{age:18}
console.log(b.__proto__, b.__proto__ === B.prototype) //{constructor: B, fn: ?} , true
3.1 類的繼承

通過extends關(guān)鍵字繼承堪夭。
子類沒有自己的this對象愕把,必須在constructor方法中調(diào)用super方法繼承父類的this對象。

  • 子類實例化時,先執(zhí)行子類構(gòu)造函數(shù),再執(zhí)行父類構(gòu)造函數(shù)
  • 子類中默認(rèn)(隱式)存在如下構(gòu)造函數(shù),通過super將子類的參數(shù)傳給父類
constructor(){
  super(...arguments)
}
  • 在子類中可以通過super訪問父類的原型對象(__proto__)
  • 通過super調(diào)用父類的方法時森爽,會綁定子類的this(即super.fn.call(this))
class Animal{
    constructor(age){
        this.age = age;
    }
    shout(){
        return "wowow"
    }
    say(){
        console.log(1,this.shout());
    }
    jump(){
        console.log('father jump');
    }

}

class Person extends Animal{
    //constructor(){
    //  super(...arguments)
    //}
    shout(){
        return "meomeo"
    }
    say(){
        console.log(2,this.shout());
        this.jump();
        super.jump();
    }
    jump(){
        console.log('child jump');
    }
}

var peter = new Person(5);
console.log(peter);//{age: 5}
peter.say();//2 meomeo  child jump  father jump
console.log(peter.constructor);//Person 
console.log(typeof peter);//object
console.log(peter instanceof Person);//true
console.log(peter instanceof Animal);//true
  • 類繼承的原型鏈
    繼承包含三種內(nèi)容:實例成員恨豁、靜態(tài)成員、函數(shù)
  class A{
    static bar = "bar"
    foo = "foo"
    show_foo(){
        console.log(this.foo)
    }
  }
  class B extends A{

  }

  let b = new B()
  console.log(b) //{foo: 'foo'}
  console.log(B.bar) //bar
  b.show_foo() //foo

等價于

  function A() {
    this.foo = "foo"
  }
  A.bar = "bar"

  A.prototype.show_foo = function() {
    console.log(this.foo)
  }

  function B() {
    A.call(this) // 繼承實例成員
  }

  B.prototype.__proto__ = A.prototype // 繼承函數(shù)
  B.__proto__ = A // 繼承靜態(tài)成員

  let b = new B()
  console.log(b) //{foo: 'foo'}
  console.log(B.bar) //bar
  b.show_foo() //foo

顯然以下內(nèi)容恒成立:

B.prototype.__proto__ === A.prototype
a.constructor === A.prototype.constructor === A
a.__proto__ === A.prototype
A.__proto__ // Native Code
B.__proto__ === A
//綜上
B.prototype.__proto__ === B.__proto__.prototype
3.2 靜態(tài)屬性和靜態(tài)方法

靜態(tài)屬性/方法指的是 Class 本身的屬性/方法爬迟, 而不是定義在實例對象上的屬性/方法橘蜜。不需要實例化類,即可直接通過該類來調(diào)用付呕。

ES6中计福,static只能修飾方法,不能修飾屬性徽职。class內(nèi)直接定義的屬性都是原型屬性象颖。
ES7中,static 可以修飾屬性姆钉,class內(nèi)直接定義的屬性都是實例屬性

  • 靜態(tài)關(guān)鍵字static说订,或直接在class外自行添加。
  • 靜態(tài)屬性/方法不會被實例繼承潮瓶,僅會被子類繼承陶冷,且依然為靜態(tài)。
  • 子類的靜態(tài)方法中筋讨,可以通過super調(diào)用父類的靜態(tài)屬性/方法埃叭。
class Box {
    static a() {
        return 100;
    }
    static value = 500
}
Box.b = 1;
class Desk extends Box {
    static a(){
        return super.a() + super.b;
    }
}
console.log(Desk.a()); //101
3.3 類的this指向
  • 類中默認(rèn)為嚴(yán)格模式,即使匿名函數(shù)悉罕,其this也不會指向window
  • 靜態(tài)成員中的this指向類赤屋,實例成員中的this指向?qū)嵗贤ㄓ玫膖his規(guī)則(指向調(diào)用者)壁袄。同理类早,如將其賦值給一個變量,再調(diào)用該變量時嗜逻,this指向會改變:
class Logger {
  printName(name = 'there') {
    this.print(`Hello ${name}`);
  }
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined

因此可以采用如下方式保證指向

  1. 在構(gòu)造方法中綁定this
class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }
  // ...
}
  1. 構(gòu)造函數(shù)內(nèi)使用箭頭函數(shù)定義方法
class Obj {
    constructor(){
      this.printName=(name = 'there')=>{
        this.print(`Hello ${name}`);
      }
    }
}
  1. 構(gòu)造函數(shù)外使用箭頭函數(shù)定義方法(class fields中的實驗性語法涩僻,可能有兼容問題)
class Logger {
    printName = (name = 'there') => {
      this.print(`Hello ${name}`);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子逆日,更是在濱河造成了極大的恐慌嵌巷,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件室抽,死亡現(xiàn)場離奇詭異搪哪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坪圾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門晓折,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兽泄,你說我怎么就攤上這事漓概。” “怎么了病梢?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵胃珍,是天一觀的道長。 經(jīng)常有香客問我蜓陌,道長堂鲜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任护奈,我火速辦了婚禮,結(jié)果婚禮上哥纫,老公的妹妹穿的比我還像新娘霉旗。我一直安慰自己,他們只是感情好蛀骇,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布厌秒。 她就那樣靜靜地躺著,像睡著了一般擅憔。 火紅的嫁衣襯著肌膚如雪鸵闪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天暑诸,我揣著相機(jī)與錄音蚌讼,去河邊找鬼。 笑死个榕,一個胖子當(dāng)著我的面吹牛篡石,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播西采,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼凰萨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胖眷,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤武通,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后珊搀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冶忱,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年食棕,在試婚紗的時候發(fā)現(xiàn)自己被綠了朗和。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡簿晓,死狀恐怖眶拉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情憔儿,我是刑警寧澤忆植,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站谒臼,受9級特大地震影響朝刊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜈缤,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一拾氓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧底哥,春花似錦咙鞍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孵奶,卻和暖如春疲酌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背了袁。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工朗恳, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人早像。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓僻肖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親卢鹦。 傳聞我的和親對象是個殘疾皇子臀脏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

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

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,513評論 1 51
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理劝堪,服務(wù)發(fā)現(xiàn),斷路器揉稚,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,219評論 0 4
  • 一直以來都比較喜歡像易中天這樣的大家秒啦,《讀城記》這本書是我在圖書館偶然間遇到,因為作者是易中天搀玖,我借來了它來讀余境,因...
    城居筆記閱讀 2,759評論 2 4
  • 1、演講訓(xùn)練臉還是往常的燒灌诅,再繼續(xù)鍛煉芳来,平時要積累素材。 2猜拾、昨天由于早起塞車頭下午開始痛即舌,平時要早睡,白天要學(xué)習(xí)...
    一只永不止步的龍閱讀 177評論 0 0