国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

詳解 TypeScript 函數(shù)聲明和重載

開發(fā) 前端
在 JavaScript 中,函數(shù)是構(gòu)建應(yīng)用的一塊基石,我們可以使用函數(shù)抽離可復(fù)用的邏輯、抽象模型、封裝過程。在TypeScript中,函數(shù)仍然是最基本、最重要的概念之一。下面就來看看TypeScript中的函數(shù)類型是如何定義和使用的。

在 JavaScript 中,函數(shù)是構(gòu)建應(yīng)用的一塊基石,我們可以使用函數(shù)抽離可復(fù)用的邏輯、抽象模型、封裝過程。在TypeScript中,函數(shù)仍然是最基本、最重要的概念之一。下面就來看看TypeScript中的函數(shù)類型是如何定義和使用的。

一、函數(shù)類型定義

1. 直接定義

函數(shù)類型的定義包括對參數(shù)和返回值的類型定義:

  1. function add(arg1: number, arg2: number): number { 
  2.   return x + y; 
  3. const add = (arg1: number, arg2: number): number => { 
  4.   return x + y; 
  5. }; 

這里用function字面量和箭頭函數(shù)兩種形式定義了add函數(shù)。函數(shù)參數(shù) arg1 和 arg2 都是數(shù)值類型,最后通過相加得到的結(jié)果也是數(shù)值類型。

如果在這里省略參數(shù)的類型,TypeScript 會默認(rèn)這個參數(shù)是 any 類型;如果省略返回值的類型,如果函數(shù)無返回值,那么 TypeScript 會默認(rèn)函數(shù)返回值是 void 類型;如果函數(shù)有返回值,那么 TypeScript 會根據(jù)定義的邏輯推斷出返回類型。

需要注意,在TypeScript中,如果函數(shù)沒有返回值,并且我們顯式的定義了這個函數(shù)的返回值類型為 undefined,那就會報錯:A function whose declared type is neither 'void' nor 'any' must return a value。正確的做法就是上面說的,將函數(shù)的返回值類型聲明為void:

  1. function fn(x: number): void { 
  2.  console.log(x) 

一個函數(shù)的定義包括函數(shù)名、參數(shù)、邏輯和返回值。為函數(shù)定義類型時,完整的定義應(yīng)該包括參數(shù)類型和返回值類型。上面都是在定義函數(shù)的指定參數(shù)類型和返回值類型。下面來定義一個完整的函數(shù)類型,以及用這個函數(shù)類型來規(guī)定一個函數(shù)定義時參數(shù)和返回值需要符合的類型。

  1. let add: (x: number, y: number) => number; 
  2. add = (arg1: number, arg2: number): number => arg1 + arg2; 
  3. add = (arg1: string, arg2: string): string => arg1 + arg2; // error 

這里定義了一個變量 add,給它指定了函數(shù)類型,也就是(x: number, y: number) => number,這個函數(shù)類型包含參數(shù)和返回值的類型。然后給 add 賦了一個實際的函數(shù),這個函數(shù)參數(shù)類型和返回類型都和函數(shù)類型中定義的一致,所以可以賦值。后面又給它賦了一個新函數(shù),而這個函數(shù)的參數(shù)類型和返回值類型都是 string 類型,這時就會報如下錯誤:

  1. 不能將類型"(arg1: string, arg2: string) => string"分配給類型"(x: number, y: number) => number"。 
  2. 參數(shù)"arg1""x" 的類型不兼容。 
  3. 不能將類型"number"分配給類型"string"。 

注意: 函數(shù)中如果使用了函數(shù)體之外定義的變量,這個變量的類型是不體現(xiàn)在函數(shù)類型定義的。

2. 接口定義

使用接口可以清晰地定義函數(shù)類型。下面來使用接口為add函數(shù)定義函數(shù)類型:

  1. interface Add { 
  2.   (x: number, y: number): number; 
  3. let addAdd = (arg1: string, arg2: string): string => arg1 + arg2;  
  4. // error 不能將類型“(arg1: string, arg2: string) => string”分配給類型“Add” 

通過接口形式定義了函數(shù)類型,這個接口Add定義了這個結(jié)構(gòu)是一個函數(shù),兩個參數(shù)類型都是number類型,返回值也是number類型。當(dāng)指定變量add類型為Add時,再要給add賦值,就必須是一個函數(shù),且參數(shù)類型和返回值類型都要滿足接口Add,顯然這個函數(shù)并不滿足條件,所以報錯了。

3. 類型別名定義

可以使用類型別名來定義函數(shù)類型,這種形式更加直觀易讀:

  1. type Add = (x: number, y: number) => number; 
  2. let addAdd = (arg1: string, arg2: string): string => arg1 + arg2;  
  3. // error 不能將類型“(arg1: string, arg2: string) => string”分配給類型“Add” 

使用type關(guān)鍵字可以給任何定義的類型起一個別名。上面定義了 Add 這個別名后,Add就成為了一個和(x: number, y: number) => number一致的類型定義。上面定義了Add類型,指定add類型為Add,但是給add賦的值并不滿足Add類型要求,所以報錯了。

注意,這里的=>與 ES6 中箭頭函數(shù)的=>不同。TypeScript 函數(shù)類型中的=>用來表示函數(shù)的定義,其左側(cè)是函數(shù)的參數(shù)類型,右側(cè)是函數(shù)的返回值類型;而 ES6 中的=>是函數(shù)的實現(xiàn)。

二、函數(shù)參數(shù)定義

1. 可選參數(shù)

TypeScript 會在編寫代碼時就檢查出調(diào)用函數(shù)時參數(shù)中存在的一些錯誤:

  1. type Add = (x: number, y: number) => number; 
  2. let addAdd = (arg1, arg2) => arg1 + arg2; 
  3. add(1, 2);    // success 
  4. add(1, 2, 3); // error 應(yīng)有 2 個參數(shù),但獲得 3 個 
  5. add(1);       // error 應(yīng)有 2 個參數(shù),但獲得 1 個 

在JavaScript中,上面代碼中后面兩個函數(shù)調(diào)用都不會報錯, 只不過add(1, 2, 3)可以返回正確結(jié)果3,add(1)會返回NaN。而在TypeScript中我們設(shè)置了指定的參數(shù),那么在使用該類型時,傳入的參數(shù)必須與定義的參數(shù)類型和數(shù)量一致。

但有時候,函數(shù)有些參數(shù)不是必須的,我們就可以將函數(shù)的參數(shù)設(shè)置為可選參數(shù)。可選參數(shù)只需在參數(shù)名后跟隨一個?即可:

  1. type Add = (x: number, y: number, z?: number) => number; 
  2. let addAdd = (arg1, arg2, arg3) => arg1 + arg2 + arg3; 
  3. add(1, 2);    // success   3 
  4. add(1, 2, 3); // success   6 

上面的代碼中,z是一個可選參數(shù),那他的類型就是number | undefined,表示參數(shù) z 就是可缺省的,那是不是意味著可缺省和類型是 undefined 等價呢?來看下面的例子:

  1. function log(x?: number) { 
  2.   console.log(x); 
  3. function log1(x: number | undefined) { 
  4.   console.log(x); 
  5. log(); 
  6. log(undefined); 
  7. log1();    // Expected 1 arguments, but got 0 
  8. log1(undefined); 

可以看到,第三次函數(shù)調(diào)用報錯了,這里的 ?: 表示在調(diào)用函數(shù)時可以不顯式的傳入?yún)?shù)。但是,如果聲明了參數(shù)類型為 number | undefined,就表示函數(shù)參數(shù)是不可缺省且類型必須是 number 或者 undfined。

需要注意,可選參數(shù)必須放在必選參數(shù)后面,這和在 JS 中定義函數(shù)是一致的。來看例子:

  1. type Add = (x?: number, y: number) => number;  // error 必選參數(shù)不能位于可選參數(shù)后。 

在TypeScript中,可選參數(shù)必須放到最后,上面把可選參數(shù)x放到了必選參數(shù)y前面,所以報錯了。在 JavaScript 中是沒有可選參數(shù)這個概念的,只不過在編寫邏輯時,可能會判斷某個參數(shù)是否為undefined,如果是則說明調(diào)用該函數(shù)的時候沒有傳這個參數(shù),要做下兼容處理;而如果幾個參數(shù)中,前面的參數(shù)是可不傳的,后面的參數(shù)是需要傳的,就需要在該可不傳的參數(shù)位置傳入一個 undefined 占位才行。

2. 默認(rèn)參數(shù)

在 ES6 標(biāo)準(zhǔn)出來之前,默認(rèn)參數(shù)實現(xiàn)起來比較繁瑣:

  1. var count = 0; 
  2. function counter(step) { 
  3.   step = step || 1; 
  4.   count += step; 

上面定義了一個計數(shù)器增值函數(shù),這個函數(shù)有一個參數(shù) step,即每次增加的步長,如果不傳入?yún)?shù),那么 step 接受到的就是 undefined,undefined 轉(zhuǎn)換為布爾值是 false,所以 step || 1 這里取了 1,從而達到了不傳參數(shù)默認(rèn) step === 1 的效果。

在 ES6 中,定義函數(shù)時給參數(shù)設(shè)默認(rèn)值直接在參數(shù)后面使用等號連接默認(rèn)值即可:

  1. const count = 0; 
  2. const counter = (step = 1) => { 
  3.   count += step; 
  4. }; 

當(dāng)為參數(shù)指定了默認(rèn)參數(shù)時,TypeScript 會識別默認(rèn)參數(shù)的類型;當(dāng)調(diào)用函數(shù)時,如果給這個帶默認(rèn)值的參數(shù)傳了別的類型的參數(shù)則會報錯:

  1. const add = (x: number, y = 2) => { 
  2.   return x + y; 
  3. }; 
  4. add(1, "ts"); // error 類型"string"的參數(shù)不能賦給類型"number"的參數(shù) 

當(dāng)然也可以顯式地給默認(rèn)參數(shù) y 設(shè)置類型:

  1. const add = (x: number, y: number = 2) => { 
  2.   return x + y; 
  3. }; 

注意:函數(shù)的默認(rèn)參數(shù)類型必須是參數(shù)類型的子類型,如下代碼:

  1. const add = (x: number, y: number | string = 2) => { 
  2.   return x + y; 
  3. }; 

這里 add 函數(shù)參數(shù) y 的類型為可選的聯(lián)合類型 number | string,但是因為默認(rèn)參數(shù)數(shù)字類型是聯(lián)合類型 number | string 的子類型,所以 TypeScript 也會檢查通過。

3. 剩余參數(shù)

在 JavaScript 中,如果定義一個函數(shù),這個函數(shù)可以輸入任意個數(shù)的參數(shù),那么就無法在定義參數(shù)列表的時候挨個定義。在 ES6 發(fā)布之前,需要用 arguments 來獲取參數(shù)列表。arguments 是一個類數(shù)組對象,它包含在函數(shù)調(diào)用時傳入函數(shù)的所有實際參數(shù),它還包含一個 length 屬性,表示參數(shù)個數(shù)。下面來模擬實現(xiàn)函數(shù)的重載:

  1. function handleData() { 
  2.   if (arguments.length === 1) return arguments[0] * 2; 
  3.   else if (arguments.length === 2) return arguments[0] * arguments[1]; 
  4.   else return Array.prototype.slice.apply(arguments).join("_"); 
  5. handleData(2); // 4 
  6. handleData(2, 3); // 6 
  7. handleData(1, 2, 3, 4, 5); // '1_2_3_4_5' 

這段代碼如果在TypeScript環(huán)境中執(zhí)行,三次handleData的調(diào)用都會報錯,因為handleData函數(shù)定義的時候沒有參數(shù)。

在 ES6 中,加入了…拓展運算符,它可以將一個函數(shù)或?qū)ο筮M行拆解。它還支持用在函數(shù)的參數(shù)列表中,用來處理任意數(shù)量的參數(shù):

  1. const handleData = (arg1, ...args) => { 
  2.   console.log(args); 
  3. }; 
  4. handleData(1, 2, 3, 4, 5); // [ 2, 3, 4, 5 ] 

在 TypeScript 中可以為剩余參數(shù)指定類型:

  1. const handleData = (arg1: number, ...args: number[]) => { 
  2.  
  3. }; 
  4. handleData(1, "a"); // error 類型"string"的參數(shù)不能賦給類型"number"的參數(shù) 

三、函數(shù)重載

在多數(shù)的函數(shù)中,是只能接受一組固定的參數(shù)。但是一些函數(shù)可以接收可變數(shù)量的參數(shù)、不同類型的參數(shù),甚至可以根據(jù)調(diào)用函數(shù)的方式來返回不同類型的參數(shù)。要使用此類函數(shù),TypeScript我們提供了函數(shù)重載功能。下面來看看函數(shù)重載是如何工作的。

1. 函數(shù)簽名

先來看一個簡單的例子:

  1. function greet(person: string): string { 
  2.   return `Hello, ${person}!`; 
  3.  
  4. greet('World'); // 'Hello, World!' 

這里的greet方法接收一個參數(shù)name,類型為string。那如果想讓greet方法來接收一組名稱怎么辦?那這時greet函數(shù)會接收字符串或字符串?dāng)?shù)組作為參數(shù),并返回字符串或字符串?dāng)?shù)組。那該如何改造這個函數(shù)?主要有兩種方式:通過判斷參數(shù)類型來修改函數(shù)簽名

  1. function greet(person: string | string[]): string | string[] { 
  2.   if (typeof person === 'string') { 
  3.     return `Hello, ${person}!`; 
  4.   } else if (Array.isArray(person)) { 
  5.     return person.map(name => `Hello, ${name}!`); 
  6.   } 
  7.   throw new Error('error'); 
  8.  
  9. greet('World');          // 'Hello, World!' 
  10. greet(['TS''JS']);     // ['Hello, TS!''Hello, JS!'

這是最簡單直接的方式,但是在某些情況下,我們希望單獨定義調(diào)用函數(shù)的方式,這時就可以使用函數(shù)重載。

2. 函數(shù)重載

當(dāng)修改函數(shù)簽名的方式比較復(fù)雜或者涉及到多種數(shù)據(jù)類型時,建議使用函數(shù)重載來完成。在函數(shù)重載中,我們需要定義重載簽名和實現(xiàn)簽名。重載函數(shù)簽名只定義函數(shù)的參數(shù)和返回值類型,并不會定義函數(shù)的正文。對于一個函數(shù)不同的調(diào)用方式,就可以有多個重載簽名。

下面來實現(xiàn)greet()函數(shù)的重載:

  1. // 重載簽名 
  2. function greet(person: string): string; 
  3. function greet(persons: string[]): string[]; 
  4.   
  5. // 實現(xiàn)簽名 
  6. function greet(person: unknown): unknown { 
  7.   if (typeof person === 'string') { 
  8.     return `Hello, ${person}!`; 
  9.   } else if (Array.isArray(person)) { 
  10.     return person.map(name => `Hello, ${name}!`); 
  11.   } 
  12.   throw new Error('error'); 

這里greet()函數(shù)有兩個重載簽名和一個實現(xiàn)簽名。每個重載簽名都描述了調(diào)用函數(shù)的一種方式。我們可以使用字符串參數(shù)或使用字符串參數(shù)數(shù)組來調(diào)用greet()函數(shù)。

現(xiàn)在就可以使用字符串或字符串?dāng)?shù)組的參數(shù)調(diào)用greet()):

  1. greet('World');          // 'Hello, World!' 
  2. greet(['TS''JS']);     // ['Hello, TS!''Hello, JS!'

在定義函數(shù)重載時,需要注意以下兩點:

(1)函數(shù)簽名是可以調(diào)用的

雖然上面我們定義了重載簽名和簽名方法,但是簽名實現(xiàn)時不能直接調(diào)用的,只有重載簽名可以調(diào)用:

  1. const someValue: unknown = 'Unknown'
  2. greet(someValue); 

這樣調(diào)用的話就會報錯:

  1. No overload matches this call. 
  2. Overload 1 of 2, '(person: string): string', gave the following error. 
  3.  Argument of type 'unknown' is not assignable to parameter of type 'string'
  4. Overload 2 of 2, '(persons: string[]): string[]', gave the following error. 
  5.   Argument of type 'unknown' is not assignable to parameter of type 'string[]' 

也就是說,即使簽名實現(xiàn)接收unknown類型的參數(shù),但是我們不能直接給greet()方法來傳遞unknown類型的參數(shù),參數(shù)只能是函數(shù)重載簽名中定義的參數(shù)類型。

(2)實現(xiàn)簽名必須是通用的

在實現(xiàn)簽名時,定義的數(shù)據(jù)類型需要是通用的,以包含重載簽名。假如我們把greet()方法的返回值類型定義為string,這時就會出問題了:

  1. function greet(person: string): string; 
  2. function greet(persons: string[]): string[]; 
  3.  
  4. function greet(person: unknown): string { 
  5.   // ... 
  6.   throw new Error('error'); 

此時string[]類型就會和string不兼容。所以,實現(xiàn)簽名的返回類型和參數(shù)類型都要包含所有重載簽名中的參數(shù)類型和返回值類型,保證是通用的。

3. 方法重載

除了常規(guī)函數(shù)外,類中的方法也可以過載,比如用重載方法greet()來實現(xiàn)一個類:

  1. class Greeter { 
  2.   message: string; 
  3.   
  4.   constructor(message: string) { 
  5.     this.message = message; 
  6.   } 
  7.   
  8.   greet(person: string): string; 
  9.   greet(persons: string[]): string[]; 
  10.  
  11.   greet(person: unknown): unknown { 
  12.     if (typeof person === 'string') { 
  13.       return `${this.message}, ${person}!`; 
  14.     } else if (Array.isArray(person)) { 
  15.       return person.map(name => `${this.message}, ${name}!`); 
  16.     } 
  17.     throw new Error('error'); 
  18.   } 

Greeter類中包含了greet()重載方法:這里面有兩個描述如何調(diào)用方法的重載簽名,以及包含其實現(xiàn)簽名。這樣我們就可以通過兩種方式調(diào)用hi.greet():

  1. const hi = new Greeter('Hi'); 
  2.   
  3. hi.greet('World');          // 'Hello, World!' 
  4. hi.greet(['TS''JS']);     // ['Hello, TS!''Hello, JS!'

 

責(zé)任編輯:武曉燕 來源: 前端充電寶
相關(guān)推薦

2023-04-14 15:44:20

TypeScrip函數(shù)重載

2021-12-10 09:11:36

TypeScript 函數(shù)重載 TS 前端

2017-08-01 00:19:15

Javascript函數(shù)函數(shù)聲明

2025-06-27 06:42:01

2009-11-16 16:59:03

PHP構(gòu)造函數(shù)

2022-02-28 08:17:24

重載函數(shù)JS前端

2016-10-11 13:32:50

函數(shù)式TypeScriptJavascript

2011-05-30 16:11:46

Javascript

2009-07-31 16:00:30

C#函數(shù)重載

2010-01-18 16:56:30

C++函數(shù)

2009-12-22 16:36:38

WCF重載

2016-12-26 09:23:18

C++函數(shù)覆蓋

2016-09-30 09:43:17

JavascriptTypeScript函數(shù)式編程

2024-04-15 12:54:40

2021-11-08 11:02:01

Go函數(shù)重載

2024-11-13 19:03:14

2021-06-28 08:01:57

JS 函數(shù)表達式函數(shù)聲明

2025-12-08 02:00:00

TypeScriptJavaScript前端

2009-09-01 11:28:32

C#使用函數(shù)重載

2010-01-20 17:48:07

C++ 函數(shù)重載
點贊
收藏

51CTO技術(shù)棧公眾號

亚洲免费毛片网站| 国产亚洲网站| 水莓100在线视频| 91香蕉亚洲精品| 91精品视频网| 成人的网站免费观看| 久久av免费看| 男人天堂久久久| 国产真人做爰毛片视频直播| 国产91精品久久久| 欧美日韩一区成人| 丁香一区二区三区| 波多野结衣的一区二区三区| av网页在线| 亚洲美免无码中文字幕在线 | 91精品视频观看| 亚洲精品福利在线观看| 欧美国产激情一区二区三区蜜月| 欧美在线日韩| 日本一区二区三区视频在线| 嫩草影院2018| 亚洲AV无码成人精品一区| 欧洲一区二区视频| 欧美videos大乳护士334| 国产精品久久毛片| 日本欧美久久久久免费播放网| 国产伦乱精品| 丝袜在线视频| wwwav91com| 日韩在线三级| 97精品伊人久久久大香线蕉| 欧美一级日韩免费不卡| 日韩一区中文字幕| 午夜在线观看免费一区| 美女网站色精品尤物极品姐弟| 污视频网站在线免费| 日本中文视频| 国产原创中文在线观看| 久久一区二区三区av| 久久久久在线观看| 亚洲国产天堂久久综合网| 亚洲成人tv网| 大桥未久av一区二区三区中文| 欧美ab在线视频| 亚洲视频三区| 性欧美1819sex性高清大胸| 男人天堂v视频| av日韩在线看| 国产一区二区黄色| 欧洲一区二区视频| 最近更新的2019中文字幕 | 久久aⅴ国产欧美74aaa| 日产午夜精品一线二线三线| 青青青国产精品| av网站在线免费| 在线看片免费人成视久网| 欧美色图另类小说| 亚洲欧洲日夜超级视频| 91香蕉国产在线观看| 97在线观看免费| 中文字幕av一区二区| 日韩欧美一二三区| 欧美日韩在线视频首页| 正在播放日韩精品| 综合久久精品| 欧美手机在线视频| 亚洲欧美中文字幕| 欧美在线观看网址综合| 国产精品igao视频| 国产又爽又黄的激情精品视频| 国产亚洲精品久久久久动| 精品91久久| 成人精品一区二区| 国产精品三级a三级三级午夜| 少妇一晚三次一区二区三区| 欧美日韩日本网| 99久久国产免费免费| 国产精品电影网| 777精品视频| 久久天堂av综合合色| 精品亚洲国产成av人片传媒| 精品婷婷伊人一区三区三| 亚洲午夜电影网| 亚洲四区在线观看| 中文字幕免费在线观看视频一区| 成人三级在线视频| 国产呦精品一区二区三区网站| 午夜宅男久久久| 极品中文字幕一区| 99久久精品费精品国产| 国产欧美日韩免费观看| 91国内精品| 国产一区二区| 国产成人久久精品一区二区三区| 日本肉肉一区| 超碰这里只有精品| 成人交换视频| 另类一区二区三区| 亚洲青青一区| 日本一区二区三区电影免费观看| 亚洲爽爆av| 二区三区精品| 美女日韩一区| 日韩中文字幕| 韩国精品福利一区二区三区| 麻豆成人入口| 国产99久久精品一区二区300| 国产精品探花在线观看| 精品国产123区| 水蜜桃久久夜色精品一区| 91亚洲成人| 欧美成人日本| 在线国产欧美| 午夜在线视频观看日韩17c| 日韩电影在线观看电影| 久久99精品久久久久| 国产精品91一区二区| 99精品偷自拍| 国产精品私人影院| 亚洲一区二区三区在线播放| 欧美日韩亚洲成人| 欧美视频一区二区三区| 欧美一区二区三区思思人| 亚洲第一视频网| 中文字幕日韩电影| 欧美精品电影在线| 国产精品久久久久久久久久东京| 亚洲一区二区三区乱码aⅴ| 官网99热精品| 日韩视频专区| 隔壁人妻偷人bd中字| 日韩福利视频在线| 特黄特色大片免费视频大全| 男人久久精品| 成人影院免费观看| xxx性欧美| www.欧美| 小说区图片区色综合区| 久久久久亚洲| 日本不卡视频一二三区| 99久久久精品| 亚洲人成亚洲人成在线观看图片| 色婷婷av一区二区三区软件| 欧美精品123区| 国产亚洲精品91在线| 久久欧美在线电影| 91精品在线一区| 性欧美videosex高清少妇| 国产老熟妇精品观看| 精品剧情v国产在线观看| yw193.com尤物在线| 免费一二一二在线视频| 99精品国产一区二区三区2021| 国产精品久久久久久影院8一贰佰 国产精品久久久久久麻豆一区软件 | av大全在线免费看| 欧亚在线中文字幕免费| 91欧美极品| 国产精品videosex极品| 国产最新精品精品你懂的| 欧美激情资源网| 欧美在线看片a免费观看| 亚洲第一二三四五区| 欧美国产日韩在线| 99久久精品免费看国产一区二区三区| 一区二区国产日产| 三级黄色的网站| 黄色网页在线观看| 亚洲狼人综合| 艳女tv在线观看国产一区| 蜜臀av一区二区| 国产精品传媒在线| 91.麻豆视频| 欧美人与物videos| 国产精品免费在线| 国产综合av在线| 青檬在线电视剧在线观看| 欧美性猛交xxxxx免费看| mm131国产精品| 9l国产精品久久久久麻豆| 久久精品国产第一区二区三区最新章节 | 动漫美女被爆操久久久| mm131午夜| 性综艺节目av在线播放| 美女日批视频在线观看| 国产一区二区三区黄网站| 激情久久婷婷| 久久色.com| 91精品国产品国语在线不卡| 国产69精品久久久| 亚洲欧美国产不卡| 天海翼女教师无删减版电影| 不卡福利视频| 午夜欧美精品久久久久久久| 91丝袜美腿高跟国产极品老师 | 亚洲三级精品| 久久精品国产一区二区三 | 国产在线精品一区二区中文| 超碰影院在线观看| 羞羞视频在线观看不卡| 精品久久网站|