国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

香港云服务器
服務(wù)器之家 - 編程語言 - JavaScript - js教程 - 詳解Typescript里的This的使用方法

詳解Typescript里的This的使用方法

2021-12-28 17:45hardfist js教程

這篇文章主要介紹了詳解Typescript里的This的使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

this可以說是Javascript里最難理解的特性之一了,Typescript里的 this 似乎更加復(fù)雜了,Typescript里的 this 有三中場景,不同的場景都有不同意思。

  • this 參數(shù): 限制調(diào)用函數(shù)時(shí)的 this 類型
  • this 類型: 用于支持鏈?zhǔn)秸{(diào)用,尤其支持 class 繼承的鏈?zhǔn)秸{(diào)用
  • ThisType: 用于構(gòu)造復(fù)雜的 factory 函數(shù)

this 參數(shù)

由于 javascript 支持靈活的函數(shù)調(diào)用方式,不同的調(diào)用場景,this 的指向也有所不同

  • 作為對象的方法調(diào)用
  • 作為普通函數(shù)調(diào)用
  • 作為構(gòu)造器調(diào)用
  • 作為 Function.prototype.call 和 Function.prototype.bind 調(diào)用

對象方法調(diào)用

這也是絕大部分 this 的使用場景,當(dāng)函數(shù)作為對象的 方法調(diào)用時(shí),this 指向該對象

?
1
2
3
4
5
6
7
const obj = {
 name: "yj",
 getName() {
 return this.name // 可以自動(dòng)推導(dǎo)為{ name:string, getName():string}類型
 },
}
obj.getName() // string類型

這里有個(gè)坑就是如果對象定義時(shí)對象方法是使用箭頭函數(shù)進(jìn)行定義,則 this 指向的并不是對象而是全局的 window,Typescript 也自動(dòng)的幫我推導(dǎo)為 window

?
1
2
3
4
5
6
7
const obj2 = {
 name: "yj",
 getName: () => {
 return this.name // check 報(bào)錯(cuò),這里的this指向的是window
 },
}
obj2.getName() // 運(yùn)行時(shí)報(bào)錯(cuò)

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

即使是通過非箭頭函數(shù)定義的函數(shù),當(dāng)將其賦值給變量,并直接通過變量調(diào)用時(shí),其運(yùn)行時(shí) this 執(zhí)行的并非對象本身

?
1
2
3
4
5
6
7
8
const obj = {
 name: "yj",
 getName() {
 return this.name
 },
}
const fn1 = obj.getName
fn1() // this指向的是window,運(yùn)行時(shí)報(bào)錯(cuò)

很不幸,上述代碼在編譯期間并未檢查出來,我們可以通過為getName添加this的類型標(biāo)注解決該問題

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Obj {
 name: string
 // 限定getName調(diào)用時(shí)的this類型
 getName(this: Obj): string
}
const obj: Obj = {
 name: "yj",
 getName() {
 return this.name
 },
}
obj.getName() // check ok
const fn1 = obj.getName
fn1() // check error

這樣我們就能報(bào)保證調(diào)用時(shí)的 this 的類型安全

構(gòu)造器調(diào)用

在 class 出現(xiàn)之前,一直是把 function 當(dāng)做構(gòu)造函數(shù)使用,當(dāng)通過 new 調(diào)用 function 時(shí),構(gòu)造器里的 this 就指向返回對象

?
1
2
3
4
5
6
7
function People(name: string) {
 this.name = name // check error
}
People.prototype.getName = function() {
 return this.name
}
const people = new People() // check error

很不幸,Typescript 暫時(shí)對 ES5 的 constructor function 的類型推斷暫時(shí)并未支持 https://github.com/microsoft/TypeScript/issues/18171), 沒辦法推導(dǎo)出 this 的類型和 people 可以作為構(gòu)造函數(shù)調(diào)用,因此需要顯示的進(jìn)行類型標(biāo)注

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface People {
 name: string
 getName(): string
}
interface PeopleConstructor {
 new (name: string): People // 聲明可以作為構(gòu)造函數(shù)調(diào)用
 prototype: People // 聲明prototype,支持后續(xù)修改prototype
}
const ctor = (function(this: People, name: string) {
 this.name = name
} as unknown) as PeopleConstructor // 類型不兼容,二次轉(zhuǎn)型
 
ctor.prototype.getName = function() {
 return this.name
}
 
const people = new ctor("yj")
console.log("people:", people)
console.log(people.getName())

當(dāng)然最簡潔的方式,還是使用 class

?
1
2
3
4
5
6
7
8
9
10
11
class People {
 name: string
 constructor(name: string) {
 this.name = name // check ok
 }
 getName() {
 return this.name
 }
}
 
const people = new People("yj") // check ok

這里還有一個(gè)坑,即在 class 里 public field method 和 method 有這本質(zhì)的區(qū)別 考慮如下三種 method

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Test {
 name = 1
 method1() {
 return this.name
 }
 method2 = function() {
 return this.name // check error
 }
 method3 = () => {
 return this.name
 }
}
 
const test = new Test()
 
console.log(test.method1()) // 1
console.log(test.method2()) // 1
console.log(test.method3()) // 1

雖然上述三個(gè)代碼都能成功的輸出 1,但是有這本質(zhì)的區(qū)別

  • method1: 原型方法,動(dòng)態(tài) this,異步回調(diào)場景下需要自己手動(dòng) bind this
  • method2: 實(shí)例方法,類型報(bào)錯(cuò), 異步場景下需要手動(dòng) bind this
  • method3: 實(shí)例方法,靜態(tài) this, 異步場景下不需要手動(dòng) bind this

在我們編寫 React 應(yīng)用時(shí),大量的使用了 method3 這種自動(dòng)綁定 this 的方式, 但實(shí)際上這種做法存在較大的問題

  • 每個(gè)實(shí)例都會(huì)創(chuàng)建一個(gè)實(shí)例方法,造成了浪費(fèi)
  • 在處理繼承時(shí),會(huì)導(dǎo)致違反直覺的現(xiàn)象
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Parent {
 constructor() {
 this.setup()
 }
 
 setup = () => {
 console.log("parent")
 }
}
 
class Child extends Parent {
 constructor() {
 super()
 }
 
 setup = () => {
 console.log("child")
 }
}
 
const child = new Child() // parent
 
class Parent2 {
 constructor() {
 this.setup()
 }
 
 setup() {
 console.log("parent")
 }
}
 
class Child2 extends Parent2 {
 constructor() {
 super()
 }
 setup() {
 console.log("child")
 }
}
 
const child2 = new Child2() // child

在處理繼承的時(shí)候,如果 superclass 調(diào)用了示例方法而非原型方法,那么是無法在 subclass 里進(jìn)行 override 的,這與其他語言處理繼承的 override 的行為向左,很容出問題。 因此更加合理的方式應(yīng)該是不要使用實(shí)例方法,但是如何處理 this 的綁定問題呢。 目前較為合理的方式要么手動(dòng) bind,或者使用 decorator 來做 bind

?
1
2
3
4
5
6
7
8
import autobind from "autobind-decorator"
class Test {
 name = 1
 @autobind
 method1() {
 return this.name
 }
}

call 和 apply 調(diào)用

call 和 apply 調(diào)用沒有什么本質(zhì)區(qū)別,主要區(qū)別就是 arguments 的傳遞方式,不分別討論。和普通的函數(shù)調(diào)用相比,call 調(diào)用可以動(dòng)態(tài)的改變傳入的 this, 幸運(yùn)的是 Typescript 借助 this 參數(shù)也支持對 call 調(diào)用的類型檢查

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface People {
 name: string
}
const obj1 = {
 name: "yj",
 getName(this: People) {
 return this.name
 },
}
const obj2 = {
 name: "zrj",
}
const obj3 = {
 name2: "zrj",
}
obj1.getName.call(obj2)
obj1.getName.call(obj3) // check error

另外 call 的實(shí)現(xiàn)也非常有意思,可以簡單研究下其實(shí)現(xiàn), 我們的實(shí)現(xiàn)就叫做 call2 首先需要確定 call 里 第一個(gè)參數(shù)的類型,很明顯 第一個(gè)參數(shù) 的類型對應(yīng)的是函數(shù)里的 this 參數(shù)的類型,我們可以通過 ThisParameterType 工具來獲取一個(gè)函數(shù)的 this 參數(shù)類型

?
1
2
3
4
5
6
7
8
9
10
11
12
interface People {
 name: string
}
function ctor(this: People) {}
 
type ThisArg = ThisParameterType<typeof ctor> // 為People類型
 
ThisParameterType 的實(shí)現(xiàn)也很簡單,借助 infer type 即可
type ThisParameterType<T> = T extends (this: unknown, ...args: any[]) => any
 T extends (this: infer U, ...args: any[]) => any
 ? U
 : unknown

但是我們怎么獲取當(dāng)前函數(shù)的類型呢, 通過泛型實(shí)例化和泛型約束

?
1
2
3
4
5
6
7
8
interface CallableFunction {
 call2<T>(this: (this: T) => any, thisArg: T): any
}
interface People {
 name: string
}
function ctor(this: People) {}
ctor.call2() //

在進(jìn)行 ctor.call 調(diào)用時(shí),根據(jù) CallableFunction 的定義其 this 參數(shù)類型為 (this:T) => any, 而此時(shí)的 this 即為 ctor, 而根據(jù) ctro 的類型定義,其類型為 (this:People) => any,實(shí)例化即可得此時(shí)的 T 實(shí)例化類型為 People, 即 thisArg 的類型為 People
進(jìn)一步的添加返回值和其余參數(shù)類型

?
1
2
3
4
5
6
7
interface CallableFunction {
 call<T, A extends any[], R>(
 this: (this: T, ...args: A) => R,
 thisArg: T,
 ...args: A
 ): R
}

This Types

為了支持 fluent interface, 需要支持方法的返回類型由調(diào)用示例確定,這實(shí)際上需要類型系統(tǒng)的額外至此。考慮如下代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A {
 A1() {
 return this
 }
 A2() {
 return this
 }
}
class B extends A {
 B1() {
 return this
 }
 B2() {
 return this
 }
}
const b = new B()
const a = new A()
b.A1().B1() // 不報(bào)錯(cuò)
a.A1().B1() // 報(bào)錯(cuò)
type M1 = ReturnType<typeof b.A1> // B
type M2 = ReturnType<typeof a.A1> // A

仔細(xì)觀察上述代碼發(fā)現(xiàn),在不同的情況下,A1 的返回類型實(shí)際上是和調(diào)用對象有關(guān)的而非固定,只有這樣才能支持如下的鏈?zhǔn)秸{(diào)用,保證每一步調(diào)用都是類型安全

?
1
2
3
4
b.A1()
 .B1()
 .A2()
 .B2() // check ok

this 的處理還有其特殊之處,大部分語言對 this 的處理,都是將其作為隱式的參數(shù)處理,但是對于函數(shù)來講其參數(shù)應(yīng)該是逆變的,但是 this 的處理實(shí)際上是當(dāng)做協(xié)變處理的。考慮如下代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Parent {
 name: string
}
class Child extends Parent {
 age: number
}
class A {
 A1() {
 return this.A2(new Parent())
 }
 A2(arg: Parent) {}
 A3(arg: string) {}
}
class B extends A {
 A1() {
 // 不報(bào)錯(cuò),this特殊處理,視為協(xié)變
 return this.A2(new Parent())
 }
 A2(arg: Child) {} // flow下報(bào)錯(cuò),typescript沒報(bào)錯(cuò)
 A3(arg: number) {} // flow和typescript下均報(bào)錯(cuò)
}

這里還要提的一點(diǎn)是 Typescript 處于兼容考慮,對方法進(jìn)行了雙變處理,但是函數(shù)還是采用了逆變,相比之下 flow 則安全了許多,方法也采用了逆變處理

ThisType

Vue2.x 最令人詬病的一點(diǎn)就是對 Typescript 的羸弱支持,其根源也在于 vue2.x 的 api 大量使用了 this,造成其類型難以推斷,Vue2.5 通過 ThisType 對 vue 的 typescript 支持進(jìn)行了一波增強(qiáng),但還是有不足之處,Vue3 的一個(gè)大的賣點(diǎn)也是改進(jìn)了增強(qiáng)了對 Typescript 的支持。下面我們就研究下下 ThisType 和 vue 中是如何利用 ThisType 改進(jìn) Typescript 的支持的。

先簡單說一下 This 的決斷規(guī)則,推測對象方法的 this 類型規(guī)則如下,優(yōu)先級(jí)由低到高

對象字面量方法的 this 類型為該對象字面量本身

?
1
2
3
4
5
6
7
// containing object literal type
let foo = {
 x: "hello",
 f(n: number) {
 this //this: {x: string;f(n: number):void }
 },
}

如果對象字面量進(jìn)行了類型標(biāo)注了,則 this 類型為標(biāo)注的對象類型

?
1
2
3
4
5
6
7
8
9
10
11
12
13
type Point = {
 x: number
 y: number
 moveBy(dx: number, dy: number): void
}
 
let p: Point = {
 x: 10,
 y: 20,
 moveBy(dx, dy) {
 this // Point
 },
}

如果對象字面量的方法有 this 類型標(biāo)注了,則為標(biāo)注的 this 類型

?
1
2
3
4
5
6
let bar = {
 x: "hello",
 f(this: { message: string }) {
 this // { message: string }
 },
}

如果對象字面量的即進(jìn)行了類型標(biāo)注,同時(shí)方法也標(biāo)注了類型,則方法的標(biāo)注 this 類型優(yōu)先

?
1
2
3
4
5
6
7
8
9
10
11
12
13
type Point = {
 x: number
 y: number
 moveBy(dx: number, dy: number): void
}
 
let p: Point = {
 x: 10,
 y: 20,
 moveBy(this: { message: string }, dx, dy) {
 this // {message:string} ,方法類型標(biāo)注優(yōu)先級(jí)高于對象類型標(biāo)注
 },
}

如果對象字面量進(jìn)行了類型標(biāo)注,且該類型標(biāo)注里包含了 ThisType,那么 this 類型為 T

?
1
2
3
4
5
6
7
8
9
10
11
12
13
type Point = {
 x: number
 y: number
 moveBy: (dx: number, dy: number) => void
} & ThisType<{ message: string }>
 
let p: Point = {
 x: 10,
 y: 20,
 moveBy(dx, dy) {
 this // {message:string}
 },
}

如果對象字面量進(jìn)行了類型標(biāo)注,且類型標(biāo)注里指明了 this 類型, 則使用該標(biāo)注類型

?
1
2
3
4
5
6
7
8
9
10
11
12
13
type Point = {
 x: number
 y: number
 moveBy(this: { message: string }, dx: number, dy: number): void
}
 
let p: Point = {
 x: 10,
 y: 20,
 moveBy(dx, dy) {
 this // { message:string}
 },
}

將規(guī)則按從高到低排列如下

  • 如果方法里顯示標(biāo)注了 this 類型,這是用該標(biāo)注類型
  • 如果上述沒標(biāo)注,但是對象標(biāo)注的類型里的方法類型標(biāo)注了 this 類型,則使用該 this 類型
  • 如果上述都沒標(biāo)注,但對象標(biāo)注的類型里包含了 ThisType, 那么 this 類型為 T
  • 如果上述都沒標(biāo)注,this 類型為對象的標(biāo)注類型
  • 如果上述都沒標(biāo)注,this 類型為對象字面量類型

這里的一條重要規(guī)則就是在沒有其他類型標(biāo)注的情況下,如果對象標(biāo)注的類型里如果包含了 ThisType, 那么 this 類型為 T, 這意味著我們可以通過類型計(jì)算為我們的對象字面量添加字面量里沒存在的屬性,這對于 Vue 極其重要。 我們來看一下 Vue 的 api

?
1
2
3
4
5
6
7
8
9
10
11
12
13
import Vue from 'vue';
export const Component = Vue.extend({
 data(){
 return {
  msg: 'hello'
 }
 }
 methods:{
 greet(){
  return this.msg + 'world';
 }
 }
})

這里的一個(gè)主要問題是 greet 是 methods 的方法,其 this 默認(rèn)是 methods 這個(gè)對象字面量的類型,因此無法從中區(qū)獲取 data 的類型,所以主要難題是如何在 methods.greet 里類型安全的訪問到 data 里的 msg。 借助于泛型推導(dǎo)和 ThisType 可以很輕松的實(shí)現(xiàn),下面讓我們自己實(shí)現(xiàn)一些這個(gè) api

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type ObjectDescriptor<D, M> = {
 data: () => D
 methods: M & ThisType<D & M>
}
 
declare function extend<D, M>(obj: ObjectDescriptor<D, M>): D & M
 
const x = extend({
 data() {
 return {
  msg: "hello",
 }
 },
 methods: {
 greet() {
  return this.msg + "world" // check
 },
 },
})

其推導(dǎo)規(guī)則如下 首先根據(jù)對象字面量的類型和泛型約束對比, 可得到類型參數(shù) T 和 M 的實(shí)例化類型結(jié)果

?
1
2
3
4
D: { msg: string}
M: {
 greet(): todo
}

接著推導(dǎo) ObjectDescriptor 類型為

?
1
2
3
4
5
6
{
 data(): { msg: string},
 methods: {
 greet(): string
 } & ThisType<{msg:string} & {greet(): todo}>
}

接著借助推導(dǎo)出來的 ObjectDescriptor 推導(dǎo)出 greet 里的 this 類型為

?
1
{ msg: string} & { greet(): todo}

因此推導(dǎo)出 this.msg 類型為 string,進(jìn)一步推導(dǎo)出 greet 的類型為 string,至此所有類型推完。 另外為了減小 Typescript 的類型推倒難度,應(yīng)該盡可能的顯示的標(biāo)注類型,防止出現(xiàn)循環(huán)推導(dǎo)或者造成推導(dǎo)復(fù)雜度變高等導(dǎo)致編譯速度過慢甚至出現(xiàn)死循環(huán)或者內(nèi)存耗盡的問題。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type ObjectDescriptor<D, M> = {
 data: () => D
 methods: M & ThisType<D & M>
}
 
declare function extend<D, M>(obj: ObjectDescriptor<D, M>): D & M
 
const x = extend({
 data() {
 return {
  msg: "hello",
 }
 },
 methods: {
 greet(): string {
  // 顯示的標(biāo)注返回類型,簡化推導(dǎo)
  return this.msg + "world" // check
 },
 },
})

到此這篇關(guān)于詳解Typescript里的This的使用方法的文章就介紹到這了,更多相關(guān)Typescript This內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家! 

原文鏈接:https://juejin.cn/post/6914853359350448142

延伸 · 閱讀

精彩推薦
  • js教程微信小程序?qū)崿F(xiàn)下拉加載更多商品

    微信小程序?qū)崿F(xiàn)下拉加載更多商品

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)下拉加載更多商品,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下...

    保護(hù)我方豆豆8102021-12-22
  • js教程JavaScript代碼實(shí)現(xiàn)簡單計(jì)算器

    JavaScript代碼實(shí)現(xiàn)簡單計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了JavaScript代碼實(shí)現(xiàn)簡單計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下...

    小蟲蟲~3992021-12-21
  • js教程js正則表達(dá)式簡單校驗(yàn)方法

    js正則表達(dá)式簡單校驗(yàn)方法

    在本篇文章里小編給大家整理了一篇關(guān)于js正則表達(dá)式簡單校驗(yàn)方法,有需要的朋友們可以參考下。...

    小妮淺淺11182021-12-24
  • js教程JS實(shí)現(xiàn)選項(xiàng)卡插件的兩種寫法(jQuery和class)

    JS實(shí)現(xiàn)選項(xiàng)卡插件的兩種寫法(jQuery和class)

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)選項(xiàng)卡插件的兩種寫法:jQuery和class,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參...

    南柯Seven11942021-12-22
  • js教程js閉包的9個(gè)使用場景

    js閉包的9個(gè)使用場景

    這篇文章主要介紹了js 閉包的9個(gè)使用場景,幫助大家更好的理解和學(xué)習(xí)JavaScript 閉包的使用,感興趣的朋友可以了解下...

    林恒10062021-12-22
  • js教程微信小程序視頻彈幕發(fā)送功能的實(shí)現(xiàn)

    微信小程序視頻彈幕發(fā)送功能的實(shí)現(xiàn)

    這篇文章主要介紹了微信小程序視頻彈幕發(fā)送功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的...

    保護(hù)我方豆豆4822021-12-21
  • js教程詳解JavaScript中分解數(shù)字的三種方法

    詳解JavaScript中分解數(shù)字的三種方法

    這篇文章主要介紹了在JavaScript中分解數(shù)字的三種方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下...

    Hunter網(wǎng)絡(luò)安全6052021-12-27
  • js教程如何在JavaScript中正確處理變量

    如何在JavaScript中正確處理變量

    這篇文章主要介紹了如何在JavaScript中正確處理變量,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下...

    瘋狂的技術(shù)宅10672021-12-20
825
主站蜘蛛池模板: av电影免费观看 | 色橹橹欧美在线观看视频高清 | 美日韩精品 | 天堂99x99es久久精品免费 | 欧美成人免费视频 | 亚洲精品视频免费观看 | 2019国产精品 | 亚洲国产精品激情在线观看 | 成人av网站在线观看 | 日韩精品一区二区三区中文在线 | 在线观看av网站永久 | 色婷婷综合久久久中字幕精品久久 | 久久免费公开视频 | 国产精品美女久久久 | 国产精品成人在线视频 | 精品国产一区探花在线观看 | 欧美簧片在线 | 五月婷婷视频 | 国产成人av网站 | 夜夜操天天干, | 久久伊人久久 | 久久伊99综合婷婷久久伊 | 一级特黄bbbbb免费观看 | 日韩电影一区 | 日韩有码在线播放 | 亚洲国产高清在线 | 日韩亚洲一区二区 | 91精品久久 | 日韩免费在线 | 日本精品一区二区三区在线观看视频 | 成人综合视频在线 | 久久中文字幕精品 | 91精品国产综合久久婷婷香蕉 | 国产高清视频一区二区 | 激情久久久| 亚洲视频在线免费观看 | 亚洲国产精品一区二区久久 | 精品少妇一区二区三区在线播放 | 亚洲电影在线观看 | 中国精品一区二区 | 毛片网站大全 |