亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

搞懂 Javascript中this 指向及繼承原理

why_rookie / 1874人閱讀

摘要:共享原型鏈現(xiàn)在我們還有另一個(gè)對(duì)象如圖那么和其實(shí)是同一東西,也就是。改進(jìn)通過第一節(jié)可以知道,我們可以通過原型鏈來解決重復(fù)創(chuàng)建的問題我們先創(chuàng)建一個(gè)士兵原型,然后讓士兵的指向士兵原型。所以這個(gè)是原型鏈繼承的缺點(diǎn),原因是和指向同一個(gè)地址即父類的。

在理解繼承之前,需要知道 js 的三個(gè)東西:

什么是 JS 原型鏈

this 的值到底是什么

JS 的new 到底是干什么的

想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

一、什么是 JS 原型鏈?

我們知道 JS 有對(duì)象,比如

    var obj = { name: "obj" } 

我們通過控制臺(tái)把obj 打印出來:

我們會(huì)發(fā)現(xiàn) obj已經(jīng)有幾個(gè)屬性(方法)了。那么問題來了:valueOf/toString/constructor 是怎么來?我們并沒有給 obj.valueOf 賦值呀。

上面這個(gè)圖有點(diǎn)難懂,手畫一個(gè)示意圖:

我們發(fā)現(xiàn)控制臺(tái)打出來的結(jié)果是:

obj本身有一個(gè)屬性 name (這是我們給它加的)

obj還有一個(gè)屬性叫做 __proto__(它是一個(gè)對(duì)象)

obj還有一個(gè)屬性,包括 valueOf, toString, constructor等

obj.__proto__其實(shí)也有一個(gè)叫做__proto__的屬性(console.log沒有顯示),值為 null

現(xiàn)在回到我們的問題:obj 為什么會(huì)擁有 valueOf / toString / constructor 這幾個(gè)屬性?

答案: 這跟 __proto__有關(guān) 。

當(dāng)我們「讀取」 obj.toString 時(shí),JS 引擎會(huì)做下面的事情:

看看 obj 對(duì)象本身有沒有 toString 屬性。沒有就走到下一步。

看看 obj.__proto__ 對(duì)象有沒有 toString 屬性, 發(fā)現(xiàn) obj.__proto__toString 屬性, 于是找到了,所以 obj.toString實(shí)際就是第2步中找到的 obj.__proto__.toString。

如果 obj.__proto__沒有,那么瀏覽器會(huì)繼續(xù)查看 obj.__proto__.__proto__。

如果 obj.__proto__.__proto__ 也沒有,那么瀏覽器會(huì)繼續(xù)查看 obj.__proto__.__proto__.__proto__。

5.直到找到 toString 或者 __proto__null

上面的過程,就是「讀」屬性的「搜索過程」。而這個(gè)「搜索過程」,是連著由 proto 組成的鏈子一直走的。這個(gè)鏈子,就叫做「原型鏈」。

共享原型鏈

現(xiàn)在我們還有另一個(gè)對(duì)象

var obj2 = { name: "obj2" }

如圖:

那么 obj.toStringobj2.toString 其實(shí)是同一東西, 也就是 obj2.__proto__.toString。
說白了,我們改其中的一個(gè) __proto__.toString ,那么另外一個(gè)其實(shí)也會(huì)變!

差異化

如果我們想讓 obj.toString 和 obj2.toString 的行為不同怎么做呢?
直接賦值就好了:

obj.toString = function(){ return "新的 toString 方法" }    

小結(jié)

[讀]屬性時(shí)會(huì)沿著原型鏈搜索

[新增]屬性時(shí)不會(huì)去看原型鏈

二、 this 的值到底是什么

你可能遇到過這樣的 JS 面試題:

var obj = {
  foo: function(){
    console.log(this)
  }
}

var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window   

請解釋最后兩行函數(shù)的值為什么不一樣。

函數(shù)調(diào)用

JS(ES5)里面有三種函數(shù)調(diào)用形式:

func(p1, p2) 
obj.child.method(p1, p2)
func.call(context, p1, p2) // 先不講 apply

一般,初學(xué)者都知道前兩種形式,而且認(rèn)為前兩種形式「優(yōu)于」第三種形式。

我們方方老師大姥說了,你一定要記住,第三種調(diào)用形式,才是正常調(diào)用形式:

    func.call(context, p1, p2)

其他兩種都是語法糖,可以等價(jià)地變?yōu)?call 形式:

func(p1, p2)等價(jià)于 func.call(undefined, p1, p2);

obj.child.method(p1, p2) 等價(jià)于 obj.child.method.call(obj.child, p1, p2);

至此我們的函數(shù)調(diào)用只有一種形式:

func.call(context, p1, p2)

這樣,this 就好解釋了 this就是上面 context。

this 是你 call 一個(gè)函數(shù)時(shí)傳的 context,由于你從來不用 call 形式的函數(shù)調(diào)用,所以你一直不知道。

先看 func(p1, p2) 中的 this 如何確定:

當(dāng)你寫下面代碼時(shí)

function func(){
  console.log(this)
}

func()

等價(jià)于

function func(){
  console.log(this)
}

func.call(undefined) // 可以簡寫為 func.call()

按理說打印出來的 this 應(yīng)該就是 undefined 了吧,但是瀏覽器里有一條規(guī)則:

如果你傳的 contextnull 或者 undefined,那么 window 對(duì)象就是默認(rèn)的 context(嚴(yán)格模式下默認(rèn) context 是 undefined)

因此上面的打印結(jié)果是 window。如果你希望這里的 this 不是 window,很簡單:

func.call(obj) // 那么里面的 this 就是 obj 對(duì)象了     

回到題目:

var obj = {
  foo: function(){
    console.log(this)
  }
}

var bar = obj.foo
obj.foo() // 轉(zhuǎn)換為 obj.foo.call(obj),this 就是 obj
bar() 
// 轉(zhuǎn)換為 bar.call()
// 由于沒有傳 context
// 所以 this 就是 undefined
// 最后瀏覽器給你一個(gè)默認(rèn)的 this —— window 對(duì)象    
[ ] 語法
function fn (){ console.log(this) }
var arr = [fn, fn2]
arr[0]() // 這里面的 this 又是什么呢? 

我們可以把 arr[0]( ) 想象為arr.0( ),雖然后者的語法錯(cuò)了,但是形式與轉(zhuǎn)換代碼里的 obj.child.method(p1, p2) 對(duì)應(yīng)上了,于是就可以愉快的轉(zhuǎn)換了:

        arr[0]() 
假想為    arr.0()
然后轉(zhuǎn)換為 arr.0.call(arr)
那么里面的 this 就是 arr 了

小結(jié):

this 就是你 call 一個(gè)函數(shù)時(shí),傳入的第一個(gè)參數(shù)。

如果你的函數(shù)調(diào)用不是 call 形式, 請將其轉(zhuǎn)換為 call 形式

三、JS 的 new 到底是干什么的?

我們聲明一個(gè)士兵,具有如下屬性:

var 士兵 = {
  ID: 1, // 用于區(qū)分每個(gè)士兵
  兵種:"美國大兵",
  攻擊力:5,
  生命值:42, 
  行走:function(){ /*走倆步的代碼*/},
  奔跑:function(){ /*狂奔的代碼*/  },
  死亡:function(){ /*Go die*/    },
  攻擊:function(){ /*糊他熊臉*/   },
  防御:function(){ /*護(hù)臉*/       }
}

我們制造一個(gè)士兵, 只需要這樣:

兵營.制造(士兵)           

如果需要制造 100 個(gè)士兵怎么辦呢?

循環(huán) 100 次吧:

var 士兵們 = []
var 士兵
for(var i=0; i<100; i++){
  士兵 = {
    ID: i, // ID 不能重復(fù)
    兵種:"美國大兵",
    攻擊力:5,
    生命值:42, 
    行走:function(){ /*走倆步的代碼*/},
    奔跑:function(){ /*狂奔的代碼*/  },
    死亡:function(){ /*Go die*/    },
    攻擊:function(){ /*糊他熊臉*/   },
    防御:function(){ /*護(hù)臉*/       }
  }
  士兵們.push(士兵)
}

兵營.批量制造(士兵們)

哎呀,看起來好簡單

質(zhì)疑

上面的代碼存在一個(gè)問題:浪費(fèi)了很多內(nèi)存

行走、奔跑、死亡、攻擊、防御這五個(gè)動(dòng)作對(duì)于每個(gè)士兵其實(shí)是一樣的,只需要各自引用同一個(gè)函數(shù)就可以了,沒必要重復(fù)創(chuàng)建 100 個(gè)行走、100個(gè)奔跑……

這些士兵的兵種和攻擊力都是一樣的,沒必要?jiǎng)?chuàng)建 100 次。

只有 ID 和生命值需要?jiǎng)?chuàng)建 100 次,因?yàn)槊總€(gè)士兵有自己的 ID 和生命值。

改進(jìn)

通過第一節(jié)可以知道 ,我們可以通過原型鏈來解決重復(fù)創(chuàng)建的問題:我們先創(chuàng)建一個(gè)「士兵原型」,然后讓「士兵」的 proto 指向「士兵原型」。

var 士兵原型 = {
  兵種:"美國大兵",
  攻擊力:5,
  行走:function(){ /*走倆步的代碼*/},
  奔跑:function(){ /*狂奔的代碼*/  },
  死亡:function(){ /*Go die*/    },
  攻擊:function(){ /*糊他熊臉*/   },
  防御:function(){ /*護(hù)臉*/       }
}

var 士兵們 = []
var 士兵
for(var i=0; i<100; i++){
  士兵 = {
    ID: i, // ID 不能重復(fù)
    生命值:42
  }

  /*實(shí)際工作中不要這樣寫,因?yàn)?__proto__ 不是標(biāo)準(zhǔn)屬性*/
  士兵.__proto__ = 士兵原型 

  士兵們.push(士兵)
}

兵營.批量制造(士兵們)
優(yōu)雅?

有人指出創(chuàng)建一個(gè)士兵的代碼分散在兩個(gè)地方很不優(yōu)雅,于是我們用一個(gè)函數(shù)把這兩部分聯(lián)系起來:

function 士兵(ID){
  var 臨時(shí)對(duì)象 = {};
  臨時(shí)對(duì)象.__proto__ = 士兵.原型;
  臨時(shí)對(duì)象.ID = ID;
  臨時(shí)對(duì)象.生命值 = 42;
  
  return 臨時(shí)對(duì)象;
}  

士兵.原型 = {
  兵種:"美國大兵",
  攻擊力:5,
  行走:function(){ /*走倆步的代碼*/},
  奔跑:function(){ /*狂奔的代碼*/  },
  死亡:function(){ /*Go die*/    },
  攻擊:function(){ /*糊他熊臉*/   },
  防御:function(){ /*護(hù)臉*/       }
}

// 保存為文件:士兵.js

 然后就可以愉快地引用「士兵」來創(chuàng)建士兵了:

var 士兵們 = []
for(var i=0; i<100; i++){
  士兵們.push(士兵(i))
}

兵營.批量制造(士兵們)

JS 之父看到大家都這么搞,覺得何必呢,我給你們個(gè)糖吃,于是 JS 之父創(chuàng)建了 new 關(guān)鍵字,可以讓我們少寫幾行代碼:

只要你在士兵前面使用 new 關(guān)鍵字,那么可以少做四件事情:

不用創(chuàng)建臨時(shí)對(duì)象,因?yàn)?new 會(huì)幫你做(你使用「this」就可以訪問到臨時(shí)對(duì)象);

不用綁定原型,因?yàn)?b>new 會(huì)幫你做(new 為了知道原型在哪,所以指定原型的名字 prototype);

不用 return 臨時(shí)對(duì)象,因?yàn)?new 會(huì)幫你做;

不要給原型想名字了,因?yàn)?new 指定名字為 prototype。

這一次用 new 來寫
function 士兵(ID){
  this.ID = ID
  this.生命值 = 42
}

士兵.prototype = {
  兵種:"美國大兵",
  攻擊力:5,
  行走:function(){ /*走倆步的代碼*/},
  奔跑:function(){ /*狂奔的代碼*/  },
  死亡:function(){ /*Go die*/    },
  攻擊:function(){ /*糊他熊臉*/   },
  防御:function(){ /*護(hù)臉*/       }
}

// 保存為文件:士兵.js
然后是創(chuàng)建士兵(加了一個(gè) new 關(guān)鍵字):

var 士兵們 = []
for(var i=0; i<100; i++){
  士兵們.push(new 士兵(i))
}

兵營.批量制造(士兵們)

new 的作用,就是省那么幾行代碼。(也就是所謂的語法糖)

注意 constructor 屬性

new 操作為了記錄「臨時(shí)對(duì)象是由哪個(gè)函數(shù)創(chuàng)建的」,所以預(yù)先給「士兵.prototype」加了一個(gè) constructor 屬性:

士兵.prototype = {
  constructor: 士兵
}

如果你重新對(duì)「士兵.prototype」賦值,那么這個(gè) constructor 屬性就沒了,所以你應(yīng)該這么寫:

士兵.prototype.兵種 = "美國大兵"
士兵.prototype.攻擊力 = 5
士兵.prototype.行走 = function(){ /*走倆步的代碼*/}
士兵.prototype.奔跑 = function(){ /*狂奔的代碼*/  }
士兵.prototype.死亡 = function(){ /*Go die*/    }
士兵.prototype.攻擊 = function(){ /*糊他熊臉*/   }
士兵.prototype.防御 = function(){ /*護(hù)臉*/       }

或者你也可以自己給 constructor 重新賦值:

士兵.prototype = {
  constructor: 士兵,
  兵種:"美國大兵",
  攻擊力:5,
  行走:function(){ /*走倆步的代碼*/},
  奔跑:function(){ /*狂奔的代碼*/  },
  死亡:function(){ /*Go die*/    },
  攻擊:function(){ /*糊他熊臉*/   },
  防御:function(){ /*護(hù)臉*/       }
}
四、繼承

繼承的本質(zhì)就是上面的講的原型鏈

1)借助構(gòu)造函數(shù)實(shí)現(xiàn)繼承
 function Parent1() {
   this.name = "parent1";
 }
 
 Parent1.prototype.say = function () {}
 
 function Child1() {
   Parent1.call(this);
   this.type = "child";
 }

 console.log(new Child1);

打印結(jié)果:

這個(gè)主要是借用call 來改變this的指向,通過 call 調(diào)用 Parent ,此時(shí) Parent 中的 this 是指 Child1。有個(gè)缺點(diǎn),從打印結(jié)果看出 Child1并沒有say方法,所以這種只能繼承父類的實(shí)例屬性和方法,不能繼承原型屬性/方法。

2)借助原型鏈實(shí)現(xiàn)繼承
/**
 * 借助原型鏈實(shí)現(xiàn)繼承
 */
function Parent2() {
  this.name = "parent2";
  this.play = [1, 2, 3];
}

function Child2() {
  this.type = "child2";
}
Child2.prototype = new Parent2();

console.log(new Child2);

var s1 = new Child2();
var s2 = new Child2();

打?。?/p>

通過一講的,我們知道要共享莫些屬性,需要 對(duì)象.__proto__ = 父親對(duì)象的.prototype,但實(shí)際上我們是不能直接 操作__proto__,這時(shí)我們可以借用 new 來做,所以
Child2.prototype = new Parent2(); <=> Child2.prototype.__proto__ = Parent2.prototype; 這樣我們借助 new 這個(gè)語法糖,就可以實(shí)現(xiàn)原型鏈繼承。但這里有個(gè)總是,如打印結(jié)果,我們給 s1.play新增一個(gè)值 ,s2 也跟著改了。所以這個(gè)是原型鏈繼承的缺點(diǎn),原因是 s1.__pro__ 和 s2.__pro__指向同一個(gè)地址即 父類的prototype。

3)組合方式實(shí)現(xiàn)繼承
/**
 * 組合方式
 */

function Parent3() {
  this.name = "parent3";
  this.play = [1, 2, 3];
}

Parent3.prototype.say = function () { }

function Child3 () {
  Parent3.call(this);
  this.type = "child3";
}

Child3.prototype = new Parent3();

var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(new Child3);
console.log(s3.play, s4.play)

打印:

將 1 和 2 兩種方式組合起來,就可以解決1和2存在問題,這種方式為組合繼承。這種方式有點(diǎn)缺點(diǎn)就是我實(shí)例一個(gè)對(duì)象的時(shí), 父類 new 了兩次,一次是var s3 = new Child3()對(duì)應(yīng) Child3.prototype = new Parent3()還要new 一次。

4)組合繼承的優(yōu)化1
function Parent4() {
  this.name = "parent4";
  this.play = [1, 2, 3];
}

Parent4.prototype.say = function () { }

function Child4() {
  Parent4.call(this);
  this.type = "child4";
}

Child4.prototype = Parent4.prototype;

var s5 = new Child4();
var s6 = new Child4();


這邊主要為 Child4.prototype = Parent4.prototype, 因?yàn)槲覀兺ㄟ^構(gòu)造函數(shù)就可以拿到所有屬性和實(shí)例的方法,那么現(xiàn)在我想繼承父類的原型對(duì)象,所以你直接賦值給我就行,不用在去 new 一次父類。其實(shí)這種方法還是有問題的,如果我在控制臺(tái)打印以下兩句:


從打印可以看出,此時(shí)我是沒有辦法區(qū)分一個(gè)對(duì)象 是直接 由它的子類實(shí)例化還是父類呢?我們還有一個(gè)方法判斷來判斷對(duì)象是否是類的實(shí)例,那就是用 constructor,我在控制臺(tái)打印以下內(nèi)容:

咦,你會(huì)發(fā)現(xiàn)它指向的是父類 ,這顯然不是我們想要的結(jié)果, 上面講過我們 prototype里面有一個(gè) constructor, 而我們此時(shí)子類的 prototype 指向是 父類的 prototye ,而父類prototype里面的contructor當(dāng)然是父類自己的,這個(gè)就是產(chǎn)生該問題的原因。

組合繼承的優(yōu)化2
/**
 * 組合繼承的優(yōu)化2
 */

function Parent5() {
  this.name = "parent4";
  this.play = [1, 2, 3];
}

Parent5.prototype.say = function () { }

function Child5() {
  Parent5.call(this);
  this.type = "child4";
}

Child5.prototype = Object.create(Parent5.prototype);

這里主要使用Object.create(),它的作用是將對(duì)象繼承到__proto__屬性上。舉個(gè)例子:

var test = Object.create({x:123,y:345});
console.log(test);//{}
console.log(test.x);//123
console.log(test.__proto__.x);//3
console.log(test.__proto__.x === test.x);//true

那大家可能說這樣解決了嗎,其實(shí)沒有解決,因?yàn)檫@時(shí) Child5.prototype 還是沒有自己的 constructor,它要找的話還是向自己的原型對(duì)象上找最后還是找到 Parent5.prototype, constructor還是 Parent5 ,所以要給 Child5.prototype 寫自己的 constructor:

Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
參考
什么是 JS 原型鏈? 
this 的值到底是什么?一次說清楚
JS 的 new 到底是干什么的?

你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!

交流

干貨系列文章匯總?cè)缦拢X得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/98038.html

相關(guān)文章

  • 徹底搞懂JavaScript繼承

    摘要:這正是我們想要的太棒了毫不意外的,這種繼承的方式被稱為構(gòu)造函數(shù)繼承,在中是一種關(guān)鍵的實(shí)現(xiàn)的繼承方法,相信你已經(jīng)很好的掌握了。 你應(yīng)該知道,JavaScript是一門基于原型鏈的語言,而我們今天的主題 -- 繼承就和原型鏈這一概念息息相關(guān)。甚至可以說,所謂的原型鏈就是一條繼承鏈。有些困惑了嗎?接著看下去吧。 一、構(gòu)造函數(shù),原型屬性與實(shí)例對(duì)象 要搞清楚如何在JavaScript中實(shí)現(xiàn)繼承,...

    _ivan 評(píng)論0 收藏0
  • javaScript原型原型鏈詳解(二)

    摘要:當(dāng)然這還沒完,因?yàn)槲覀冞€有重要的一步?jīng)]完成,沒錯(cuò)就是上面的第行代碼,如果沒有這行代碼實(shí)例中的指針是指向構(gòu)造函數(shù)的,這樣顯然是不對(duì)的,因?yàn)檎G闆r下應(yīng)該指向它的構(gòu)造函數(shù),因此我們需要手動(dòng)更改使重新指向?qū)ο蟆? 第一節(jié)內(nèi)容:javaScript原型及原型鏈詳解(二) 第一節(jié)中我們介紹了javascript中的原型和原型鏈,這一節(jié)我們來講利用原型和原型鏈我們可以做些什么。 普通對(duì)象的繼承 ...

    widuu 評(píng)論0 收藏0
  • 針對(duì)還沒搞懂javascriptthis關(guān)鍵字的同學(xué)

    摘要:雖然方法定義在對(duì)象里面,但是使用方法后,將方法里面的指向了。本文都是在非嚴(yán)格模式下的情況。在構(gòu)造函數(shù)內(nèi)部的內(nèi)的回調(diào)函數(shù),始終指向?qū)嵗膶?duì)象,并獲取實(shí)例化對(duì)象的的屬性每這個(gè)屬性的值都會(huì)增加。否則最后在后執(zhí)行函數(shù)執(zhí)行后輸出的是 本篇文章主要針對(duì)搞不清this指向的的同學(xué)們!不定期更新文章都是我學(xué)習(xí)過程中積累下的經(jīng)驗(yàn),還請大家多多關(guān)注我的文章以幫助更多的同學(xué),不對(duì)的地方還望留言支持改進(jìn)! ...

    Riddler 評(píng)論0 收藏0
  • 淺析JavaScript原型constructor、__proto__、prototype的關(guān)系

    摘要:搞清了構(gòu)造函數(shù)和原型的區(qū)別后,就可以繼續(xù)了。指向構(gòu)造函數(shù)的原型對(duì)象,存在于實(shí)例與構(gòu)造函數(shù)的原型對(duì)象之間。要注意的是當(dāng)我們使用下面這種將整個(gè)重寫的情況時(shí),會(huì)切斷構(gòu)造函數(shù)和原型之間的聯(lián)系,也就是說不再指向了,而是指向。 前言 先說一說為什么要搞清楚JavaScript的原型,因?yàn)檫@就是JS的根。JavaScript雖然不是一門傳統(tǒng)的面向?qū)ο笳Z言,但它有自己的類和繼承機(jī)制,最重要的就是它采用...

    wenzi 評(píng)論0 收藏0
  • 【前端芝士樹】Javascript的原型與原型鏈

    摘要:在創(chuàng)建對(duì)象不論是普通對(duì)象還是函數(shù)對(duì)象的時(shí)候,都有一個(gè)叫做的內(nèi)置屬性,用于指向創(chuàng)建它的構(gòu)造函數(shù)的原型對(duì)象,也就是。因?yàn)橐粋€(gè)普通對(duì)象的構(gòu)造函數(shù)所以原型鏈原型鏈的形成是真正是靠而非。參考文章最詳盡的原型與原型鏈終極詳解,沒有可能是。 【前端芝士樹】Javascript的原型、原型鏈以及繼承機(jī)制 前端的面試中經(jīng)常會(huì)遇到這個(gè)問題,自己也是一直似懂非懂,趁這個(gè)機(jī)會(huì)整理一下 0. 為什么會(huì)出現(xiàn)原型和...

    yy736044583 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<