成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

一文詳解JavaScript函數中的參數

函數參數是函數內部跟函數外部溝通的橋梁。下面本篇文章就來帶大家了解一下JavaScript函數中的參數,希望對大家有所幫助!

一文詳解JavaScript函數中的參數

一、函數的形參和實參

函數的參數會出現在兩個地方,分別是函數定義處和函數調用處,這兩個地方的參數是有區別的。

  • 形參(形式參數)

    在函數定義中出現的參數可以看做是一個占位符,它沒有數據,只能等到函數被調用時接收傳遞進來的數據,所以稱為形式參數,簡稱形參。

  • 實參(實際參數)

    函數被調用時給出的參數包含了實實在在的數據,會被函數內部的代碼使用,所以稱為實際參數,簡稱實參。

形參和實參的區別和聯系

  • 1) 形參變量只有在函數被調用時才會分配內存,調用結束后,立刻釋放內存,所以形參變量只有在函數內部有效,不能在函數外部使用。

  • 2) 實參可以是常量、變量、表達式、函數等,無論實參是何種類型的數據,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參,所以應該提前用賦值、輸入等辦法使實參獲得確定值。

  • 3) 實參和形參在數量上、類型上、順序上必須嚴格一致,否則會發生“類型不匹配”的錯誤。當然,如果能夠進行自動類型轉換,或者進行了強制類型轉換,那么實參類型也可以不同于形參類型。

  • 4) 函數調用中發生的數據傳遞是單向的,只能把實參的值傳遞給形參,而不能把形參的值反向地傳遞給實參;換句話說,一旦完成數據的傳遞,實參和形參就再也沒有瓜葛了,所以,在函數調用過程中,形參的值發生改變并不會影響實參。

  • 5) 形參和實參雖然可以同名,但它們之間是相互獨立的,互不影響,因為實參在函數外部有效,而形參在函數內部有效。

形參和實參的功能是傳遞數據,發生函數調用時,實參的值會傳遞給形參。

二、參數傳遞

函數允許我們將數據傳遞進去,通過傳遞的數據從而影響函數執行結果,使函數更靈活、復用性更強。

function foo(a, b) {     console.log([a, b]); }  foo(1, 2); // 輸出 [1, 2]

這個例子中,ab 屬于函數中的局部變量,只能在函數中訪問。調用函數時,傳遞的數據會根據位置來匹配對應,分別賦值給 ab

創建函數時,function 函數名 后面括號中設定的參數被稱為形參;調用函數時,函數名后面括號中傳入的參數被稱為實參。上面例子中,ab 是形參,傳入的 12 是實參。

因為形參是已聲明的變量,所以不能再用 letconst 重復聲明。

function foo(a, b) {     let a = 1; // 報錯,a 已聲明     const b = 1; // 報錯,b 已聲明 }

JavaScript 中所有函數傳遞都是按值傳遞的,不會按引用傳遞。所謂的值,就是指直接保存在變量上的值,如果把對象作為參數傳遞,那么這個值就是這個對象的引用,而不是對象本身。這里實際上是一個隱式的賦值過程,所以給函數傳遞參數時,相當于從一個變量賦值到另一個變量

原始值:

function add(num) {     return num + 1; }  let count = 5; let result = add(count); // 此處參數傳遞的過程可以看作是 num = count  console.log(count); // 5 console.log(result); // 6

引用值:

function setName(obj) {     obj.name = "小明"; }  let person = {};  setName(person); // 此處參數傳遞的過程可以看作是 obj = person; console.log(person); // {name: "小明"}

三、理解參數

JavaScript 中的函數既不會檢測參數的類型,也不會檢測傳入參數的個數。定義函數時設置兩個形參,不意味著調用時必須傳入兩個參數。實際調用時不管是傳了一個還是三個,甚至不傳參數也不會報錯。

所有函數(非箭頭)中都有一個名為 arguments 的特殊的類數組對象(不是 Array 的實例),它保存著所有實參的副本,我們可以通過它按照數組的索引訪問方式獲取所有實參的值,也可以訪問它的 arguments.length 屬性來確定函數實際調用時傳入的參數個數。

例如:

function foo(a, b) { 	console.log(arguments[0]);     console.log(arguments[1]);     console.log(arguments.length); }  foo(10, 20); // 依次輸出 10、20、2

上面例子中,foo() 函數的第一個參數是 a,第二個參數是b ,可以通過 arguments[x] 的方式來分別獲取同樣的值 。因此,你甚至可以在聲明函數時不設置形參。

function foo() { 	console.log(arguments[0]);     console.log(arguments[1]); }  foo(10, 20); // 依次輸出 10、20

由此可見,JavaScript 函數的形參只是方便使用才寫出來的。想傳多少個參數都不會產生錯誤。

還有一個要注意的是,arguments 可以跟形參一起使用,并且 arguments 對象中的值會和對應的形參保持同步。例如:

function foo(a) { 	arguments[0] ++;     console.log(a); }  foo(10); // 輸出 11 //------------------------------------ function foo2(a) { 	a++;     console.log(arguments[0]); }  foo2(10); // 輸出 11

當修改 arguments[0] 或 a 的值時,另一個也被改變了。這并不意味著它們訪問同一個內存地址,畢竟我們傳入的是一個原始值。它們在內存中還是分開的,只是由于內部的機制使它們的值保持了同步。

另外,如果缺少傳參,那這個形參的值就不會和 arguments 對象中的對應值進行同步。例如下面這個例子,只傳了一個參數,那么arguments 中只有一個實參值,這時候在函數中把 arguments[1] 設置為某個值,這個值并不會同步給第二個形參,例如:

function foo(a,b) {     arguments[1] = 2;     console.log(b); }  foo(1); // 輸出 undefined

這個例子中,形參 b 沒有傳入實參,它的值會默認為 undefined。但如果:

foo(1, undefined); // 輸出 2

手動傳入 undefined 時, arguments 數組中會出現一個值為 undefined 的元素,依然能和 b 的值進行同步。

嚴格模式下,arguments 對象中的值和形參不會再同步,當然,如果傳入的是引用值,它們依然會互相影響,但這只是引用值的特性而已。因此,在開發中最好不要依賴這種同步機制,也就是說不要同時使用形參和它在arguments 對象中的對應值。

箭頭函數中沒有 arguments

如果函數是使用箭頭語法定義的,那么函數中是沒有 arguments 對象的,只能通過定義的形參來訪問。

let foo = () => {     console.log(arguments[0]); }foo(); // 報錯,arguments 未定義

在某些情況可能會訪問到 arguments

function fn1(){     let fn2 = () => {     	console.log(arguments[0]);     }          fn2(); }fn1(5);

但這個 arguments,并不是箭頭函數的,而是屬于外部普通函數的,當箭頭函數中訪問 arguments 時,順著作用域鏈找到了外部函數的arguments

四、將對象屬性用作實參

當一個函數包含的形參有多個時,調用函數就成了一種麻煩,因為你總是要保證傳入的參數放在正確的位置上,有沒有辦法解決傳參順序的限制呢?

由于對象屬性是無序的,通過屬性名來確定對應的值。因此可以通過傳入對象的方式,以對象中的屬性作為真正的實參,這樣參數的順序就無關緊要了。

function foo(obj) {     console.log(obj.name, obj.sex, obj.age); }  foo({ sex: '男', age: 18, name: '小明' }); // 小明 男 18

五、參數默認值

如果調用函數時缺少提供實參,那么形參默認值為 undefined

有時候我們想要設置特定的默認值,在 ES6 之前還不支持顯式地設置默認值的時候,只能采用變通的方式:

function sayHi(name) {     name = name || 'everyone';      	console.log( 'Hello ' + name + '!'); }  sayHi(); // 輸出 'Hello everyone!'

通過檢查參數值的方式判斷有沒有賦值,上面的做法雖然簡便,但缺點在于如果傳入的實參對應布爾值為 false ,實參就不起作用了。需要更精確的話可以用 if 語句或者三元表達式,判斷參數是否等于 undefined,如果是則說明這個參數缺失 :

// if 語句判斷 function sayHi(name) { 	if (name === undefined) { 		name = 'everyone'; 	}      	console.log( 'Hello ' + name + '!'); }  // 三元表達式判斷 function sayHi(name) { 	name =  (name !== undefined) ? name : 'everyone'; 	     console.log( 'Hello ' + name + '!'); }

ES6 就方便了許多,因為它支持了顯式的設置默認值的方式,就像這樣:

function sayHi(name = 'everyone') { // 定義函數時,直接給形參賦值 	console.log( 'Hello ' + name + '!'); }  sayHi(); // 輸出 'Hello everyone!'  sayHi('Tony'); // 輸出 'Hello Tony!'  sayHi(undefined); // 輸出 'Hello everyone!'

這些結果表明了,它也是通過參數是否等于 undefined 來判定參數是否缺失的。

默認值不但可以是一個值,它還可以是任意合法的表達式,甚至是函數調用:

function sayHi(name = 'every'+'one') { 	console.log( 'Hello ' + name + '!'); }  sayHi(); // 輸出 'Hello everyone!'  //-------------------------------------- function foo() {     console.log('調用foo');     return 'Tony'; }  function sayHi(name = foo()) { 	console.log( 'Hello ' + name + '!'); } 		   sayHi(); // 輸出 '調用foo'          // 輸出 'Hello Tony!'   sayHi(undefined); // 輸出 '調用foo'                   // 輸出 'Hello Tony!'   sayHi('John'); // 輸出 'Hello John!'

可以看到,函數參數的默認值只有在函數調用時,參數的值缺失或者是 undefined 才會求值,不會在函數定義時求值。

參數默認值的位置

通常我們給參數設置默認值,是為了調用函數時可以適當省略參數的傳入,這里要注意的是,有多個參數時,設置了默認值的參數如果不是放在尾部,實際上它是無法省略的。

function fn(x = 1, y) { 	console.log([x, y]); }  fn(); // 輸出 [1, undefined] fn(2); // 輸出 [2, undefined] fn(, 2); // 報錯,語法錯誤(這里不支持像數組那樣的空槽) fn(undefined, 2); // 輸出 [1, 2] (那還不如傳個 1 方便呢!)

上面例子中,給形參 x 設置的默認值就顯得沒有任何意義了。因此,設置默認值的參數放在尾部是最好的做法:

function fn(x, y = 2) { 	console.log([x, y]); }  fn(); // 輸出 [undefined, 2] fn(1); // 輸出 [1, 2] fn(1, 1) // 輸出 [1, 1]

參數的省略問題

在多個參數設置了默認值的情況下,那么問題又來了,你并不能省略比較靠前的參數,而只給最后的一個參數傳入實參。

function fn(x, y = 2, z = 3) { 	console.log([x, y, z]); }  fn(1, , 10) // 報錯

前面我們知道,可以通過傳入對象的這種方式去避免參數順序的限制。那參數默認值如何實現呢?用 ||if 語句或者三元表達式去判斷也是解決辦法,但這樣就顯得有些落后了。接下來要討論的是另外兩種 ES6 中的全新方式。

參數默認值和 Object.assign() 結合使用

function fn(obj = {}) {     let defaultObj = {         x: undefined,         y: 2,         z: 3     }          let result = Object.assign(defaultObj, obj);      	console.log([result.x, result.y, result.z]); }  fn(); // 輸出 [undefined, 2, 3] fn({ x: 1, z: 10 }); // 輸出 [1, 2, 10]

上面的例子中,在函數中定義了一個對象 defaultObj ,變通地利用其中的屬性作為參數的默認值,然后利用 Object.assagin() 把傳入的對象和默認對象進行合并,defaultObj 中的屬性會被 obj 的相同屬性覆蓋,obj 中如果有其他屬性會分配給 defaultObj 。這里用一個變量接收返回的合并對象。

同時形參 obj 也設置了默認值為一個空對象,防止函數調用時不傳任何參數,因為這會導致 Object.assign() 接收的第二個參數是 undefined ,從而產生報錯。

參數默認值和解構賦值結合使用

函數調用時,實參和形參的匹配實際上是一個隱式的賦值過程,所以,參數傳遞也可以進行解構賦值:

function fn({ x, y = 2, z = 3 }) {     console.log([x, y, z]); }  fn({}); // 輸出 [undefined, 2, 3] fn({ x: 1, z: 10 }); // 輸出 [1, 2, 10]

在這個例子中,使用的只是對象的解構賦值默認值,還沒有使用函數參數的默認值。如果函數調用時不傳任何參數,也會產生報錯,因為這導致了參數初始化時解構賦值失敗,相當于執行了 {x, y = 2, z = 3} = undefined 這樣的代碼。

同樣的,你可以利用參數默認值的語法,給 {x, y = 2, z = 3} 設置一個默認的解構對象,使得不傳參函數也能夠順利執行:

function fn({ x, y = 2, z = 3 } = {}) {     console.log([x, y, z]); }  fn(); // 輸出 [undefined, 2, 3]

這里出現了雙重的默認值,可能有些繞,那么用一段偽代碼來解釋以上的參數初始化過程就是:

if( 實參 === {...} ) { // 當 fn({...});          { x, y = 2, z = 3 } = {...};                          } else if ( 實參 === undefined ){ // 當 fn();     { x, y = 2, z = 3 } = {};  }

雙重默認值有一點細節需要特別注意,就是解構賦值默認值和函數參數默認值的差別,看下面例子:

function fn ({ x = 1 } = {}, { y } = { y: 2 }){     console.log(x, y); }  fn(); // 輸出 1 2 fn({ x: 10 }, { y: 20 }); // 輸出 10 20 fn({},{}); // 1 undefined

這個函數中,有兩組參數采用了解構賦值的方式,看似 x 和 y 都設置了默認值,雖然是不同的兩種形式,但顯然不是任何情況下結果都相同的。當傳入的參數是{}時,y 并沒有獲取到默認值 2 ,為什么會這樣呢?結合前面的偽代碼例子來看:

fn({ x: 10 }, { y: 20 }); // 初始化時: { x = 1 } = { x: 10 }, { y } = { y: 20 }  fn({},{}); // 初始化時: { x = 1 } = {}, { y } = {}

當傳入的參數是{}時,函數參數沒有缺失也不是 undefined ,所以函數參數默認值是不起作用的。同時 {} 里面也沒有 x 和 y 的對應值,x 得到的 1 是解構賦值默認值,而 y 由于沒有設置解構賦值默認值,所以它默認是 undefined

參數默認值的作用域與暫時性死區

還有一個小細節,一旦有參數設置了默認值,那么它們會形成自己的作用域(包裹在(...)中),因此不能引用函數體中的變量:

function foo(a = b) {     let b = 1; }  foo(); // 報錯,b 未定義

但這個作用域只是臨時的,參數初始化完畢后,這個作用域就不存在了。

它也符合普通作用域的規則:

let b = 2;  function foo(a = b) {     let b = 1;     return a; }  foo(); // 2

上面例子中,存在一個全局變量 b,那么形參 a 會獲取到全局變量 b 的值。

當然,如果形參作用域中存在一個形參 b 的話,它優先獲取到的是當前作用域的:

let b = 2;  function foo(b = 3 ,a = b) {     return a; }  foo(); // 3

給多個參數設置默認值,它們會按順序初始化的,遵循“暫時性死區”的規則,即前面的參數不能引用后面的參數:

function foo(a = b, b = 2) {     return a + b; }  foo(); // 報錯,b 在初始化之前不能訪問

六、參數的收集與展開

剩余參數

ES6 提供了**剩余參數(rest)**的語法(...變量名),它可以收集函數多余的實參(即沒有對應形參的實參),這樣就不再需要使用 arguments 對象來獲取了。形參使用了 ... 操作符會變成一個數組,多余的實參都會被放進這個數組中。

剩余參數基本用法:

function sum(a, ...values) {       for (let val of values) {         a += val;     }          return a; }  sum(0, 1, 2, 3); // 6

上面例子中,在參數初始化時,首先根據參數位置進行匹配,把 0 賦值給 a ,然后剩余的參數 1、2、3 都會被放進數組 values 中。

下面是分別用 arguments 對象和剩余參數來獲取參數的對比例子:

// arguments 的寫法 function sortNumbers() { 	return Array.prototype.slice.call(arguments).sort(); }  // 剩余參數的寫法 const sortNumbers = (...numbers) => {     return numbers.sort(); }

可以看出剩余參數的寫法更加簡潔。盡管 arguments 是一個類數組,也是可迭代對象,但它終究不是數組。它不支持數組方法,當我們使用 arguments 時,如果想要調用數組方法,就必須使用Array.prototype.slice.call先將其轉為數組。

而剩余參數它不同于 arguments 對象,它是真正的 Array 實例,能夠很方便地使用數組方法。并且箭頭函數也支持剩余參數。

另外,使用剩余參數不會影響 arguments 對象的功能,它仍然能夠反映調用函數時傳入的參數。

  • 剩余參數的位置

剩余參數必須是最后一個形參,否則會報錯。

// 報錯 function fn1(a, ...rest, b) { 	console.log([a, b, rest]); }   // 正確寫法 function fn2(a, b, ...rest) {     console.log([a, b, rest]); }  fn2(1, 2, 3, 4) // 輸出 [1, 2, [3, 4]]

展開語法

前面我們知道了如何把多余的參數收集為一個數組,但有時候我們需要做一些相反的事,例如要把一個數組中的元素分別傳入給某個函數,而不是傳入一個數組,像這樣:

function sum(...values) {     let sum = 0;          for (let val of values) {         sum += val;     }          return sum; }  let arr = [1, 2, 3, 4];  sum(arr); // "01,2,3,4"

上面例子的函數會把所有傳進來的數值累加,如果直接傳入一個數組,就得不到我們想要的結果。

例子中傳入一個數組, values 的值會變成 [[1, 2, 3, 4]],導致數組 values 中只有一個元素,而這個元素的類型是數組。那么函數返回值就是數值 0 和數組 [1, 2, 3, 4]相加的結果了,兩者各自進行了類型的隱式轉換變成字符串,然后再相加,是一個字符串拼接的效果。

要實現把數組拆解傳入給函數,首先不可能一個個傳入參數——sum(arr[0], arr[1], arr[2], arr[3]);,因為不是任何時候都知道數組中有多少個元素的,而且數組中可能會非常多的元素,手動傳是不明智的。

比較可行的是借助 apply() 方法:

sum.apply(null, arr); // 10

但這還不是最優解,那么重點來了!

ES6 新增的**展開語法(spread)**可以幫助我們面對這種情況。它也是使用 ...變量名 的語法,雖然跟剩余參數語法一樣,但是用途完全相反,它能夠把一個可迭代對象拆分成逗號分隔的參數序列。

在函數調用時,它的應用是這樣子的:

sum(...arr); // 10  // 相當于 sum(1,2,3,4);

它甚至可以隨意搭配常規值使用,沒有前后位置限制,還可以同時傳入多個可迭代對象:

sum(-1, ...arr); // 9 sum(...arr, 5); // 15 sum(-1, ...arr, 5); // 14 sum(-1, ...arr, ...[5, 6, 7]); // 27

展開操作符 ... 相當于替我們完成了手動分別傳參的操作,函數只知道接收的實參是單獨的一個個值,不會因為展開操作符的存在而產生其他影響。

上面的示例雖然都是針對于數組的,但展開語法能做的還不止這些,其他可迭代對象例如字符串、字面量對象都可以展開,深入了解請參見 → 展開語法

總結

  • 形參是函數中已聲明的局部變量,傳遞給函數的實參會被賦值給形參,函數參數傳遞實際上是一個隱式的賦值過程。

  • 形參和實參的數量可以不相等:

    ● 缺失實參的形參會得到默認值 undefined

    ● 額外的實參,可以通過 arguments 對象訪問,箭頭函數除外。

  • 可以通過傳入對象的方式讓傳參順序不再重要,讓對象中的屬性作為真正的實參。

  • ES6 的參數默認值——函數調用時參數的值缺失或者是 undefined ,才會獲取默認值。

    ● 設置默認值的形參只有放在最后一位才可以省略傳參。

    ● 形參設置默認值不能引用函數體中的變量,但可以引用前面的形參和外部變量。

    ● 通過 Object.assign() 或者解構賦值實現默認值,能讓傳參的方式更加靈活。

  • 剩余參數和 arguments 的主要區別:

    ● 剩余參數只包含那些沒有對應形參的實參,而 arguments 對象包含了傳給函數的所有實參。

    ● 剩余參數是真正的 Array 實例,而 arguments 只是類數組對象。

  • 剩余參數和展開語法都采用 ... 操作符,在函數的相關場景中:

    ● 出現在函數形參列表的最后,它是剩余參數。

    ● 出現在函數調用時,它是展開語法。

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
国产成人精品2021| 高校美女内射含羞草| 被驯服的人妻佐佐木明希| 成人午夜免费无码福利片| 国产极品粉嫩馒头一线天AV| 国产色XX群视频射精| 精品深夜AV无码一区二区| 久久亚洲精品AB无码播放| 免费无遮挡很爽很污很黄的网站| 欧美肥肥婆另类XXXX000| 日日天干夜夜狠狠爱| 西西人体大胆WWW444| 亚洲色欲色欲欲WWW在线| 中文字幕精品一区二区精品| JIZZJIZZ亚洲日本少妇| 国产成人A∨麻豆精品| 好吊色欧美一区二区三区视频| 久久久久久精品免费无码| 欧美色成人综合天天影院| 兽交ZOOSKOO| 亚洲国产精品无码一区二区三区 | 亚洲国产精品久久精品成人网站| 一日本道A高清免费播放| XXXX黑大荫茎XXXX| 国产人成视频在线观看| 老司机带带我免费看| 日韩精品无码一区二区| 亚洲VA国产日韩欧美精品| 18禁亲胸揉胸膜下刺激免费网站| 粗大在少妇体内进进出出| 黑人双人RAPPER剧情介绍| 男男av在线播放| 天天玩天天玩天天玩| 亚洲熟女综合一区二区三区 | 偷拍 拍自 欧美色区| 亚洲欧美日韩精品久久亚洲区| CHINA丰满人妻VIDEOS| 国产精品人成视频免费播放| 久久亚洲精品无码爱剪辑| 日韩人妻不卡一区二区三区| 亚洲国产精品无码中文字满 | 国产精品青青在线麻豆| 免费AV大片在线观看入口| 四季AV无码专区AV| 伊在人亚洲香蕉精品区| 夫妇交换聚会群4P疯狂大战视频| 久久精品国产99国产精品亚洲 | 高H禁伦餐桌上的肉伦NP| 久久久久免费精品国产| 色欲天天天综合网| 一炕四女被窝交换啪啪| 国产JIZZJIZZ全部免费看| 久久中文字幕人妻熟AV女| 特级欧美ZOOXX| 中国内射XXXX6981少妇| 国产精品免费久久久久久蜜桃| 麻豆国产AV超爽剧情系列| 玩弄秘书的奶又大又软| 中文字幕亚洲欧美日韩在线不卡| 国产精品视频一区二区噜噜| 欧美成A高清在线观看| 亚洲AV成人一区二区三区天堂| IPHONE14欧美日韩版本| 精品久久久久久无码中文字幕一区| 日本熟妇人妻中出| 一区二区三区高清AV专区| 国产乱人伦AV在线麻豆A| 欧美性大战XXXXX久久久| 亚洲AV无码专区在线观看亚| 城中村快餐嫖老妇对白| 麻豆精产国品一二三区别| 亚洲AV激情无码专区在线下载| 白嫩白嫩BBBBBBBBB-| 久久久久亚洲精品中文字幕| 新妺妺窝人体色7777婷婷| 边做边爱完整版免费视频播放百度| 久久久久久AV无码免费网站 | 国产精品久久久天天影视香蕉| 欧美肉欲XXⅩOOO性| 亚洲午夜精品一区二区| 国产蜜桃AV秘 区一区二区三区| 奇米第四色777ME| 余年周婉小说全文免费阅读完整版| 国产免费无码一区二区| 日韩欧美亚洲每日更新在线| 2021国内精品久久久久精品 | 欧洲乱码伦视频免费| 一本一道波多野结衣AV一区| 国产人妖视频一区二区| 色噜噜亚洲男人的天堂| AV无码小缝喷白浆在线观看| 久久久亚洲AV波多野结衣| 亚洲AV综合久久九九| 国产AV一区二区精品久久| 人妻丰满熟妇AⅤ无码区| 中文在线っと好きだった官网| 精品国产一区二区三区久久久狼| 无码熟熟妇丰满人妻PORN| 大桥未久亚洲无AV码在线| 欧洲熟妇的性久久久久久| 中文字幕人成乱码熟女免费| 久久久久久精品免费S| 亚洲国产成人AV人片久久| 国产免费AV一区二区三区| 四季AV无码专区AV浪潮| 成熟闷骚女邻居引诱2| 人妻AV无码专区| 7777色情ⅩXXX欧美色妇| 浪潮AV激情高潮国产精品没电了| 亚洲精品无码成人片| 韩国无码AV片在线观看网站| 无遮挡无码H纯肉动漫在线观看 | 成 人 综合 亚洲另类| 欧美搡BBBBB搡BBBBB| 999精产国品一二三产区区| 麻豆亚洲国产成人精品无码区| 野花日本大全免费观看10电影| 精品国产三级A∨在线无码| 亚洲AV无码乱码精品观看| 国产在线孕妇孕交| 亚洲AV日韩AV永久无码电影| 国产精品乱子乱XXXX| 无码专区国产精品第一页| 国产精品无码素人福利不卡| 无码精品人妻一区二区三区漫画| 国产成人猛男69精品视频| 熟妇女领导呻吟疯狂| 丰满少妇人妻HD高清果冻传媒 | 一区二区三区AV高清免费波多| 久久久无码人妻精品无码| 亚洲熟妇一区二区| 久久久久亚洲AV无码专区首| 一本一道人人妻人人妻ΑV| 巨胸喷奶水视频WWW免费动漫| 在线观看的AV网站| 妺妺窝人体色www聚色窝| 377P欧洲日本亚洲大胆| 牛牛影视亚洲AV成人片| 阿姨呀咿呀啊咿呀咿呀| 日韩AⅤ无码AV一区二区三区| 草莓视频免费观看| 色偷拍 自怕 亚洲 10P| 国产精品国产三级国产普通话| 性欧美大战久久久久久久久| 狠狠色丁香久久婷婷综合五月 | 亚洲18色成人网站WWW| 国内精品伊人久久久影视| 亚洲国产精品久久久久秋霞1| 久久大香香蕉国产拍国| 狠狠做五月深爱婷婷| 香蕉久久夜色精品升级完成| 国内精品久久久久精品| 野花视频在线观看| 欧美成人精品第一区| 被老汉耸动呻吟双性美人| 天堂VA欧美ⅤA亚洲VA老司机| 国产婷婷成人久久AV免费高清| 亚洲国产精品日韩AV不卡在线| 久久久久久久精品国产亚洲87| 性欧美一区二区三区| 人与各种动ZZZ0O0OⅩⅩX| 国产成人亚洲精品青草| 亚洲寂寞女人AⅤ| 免费能直接看黄的视频| 八区精品色欲人妻综合网| 玩稚嫩的小屁股眼AV| 精品无码国产自产拍在线观看蜜桃| 真人无码作爱免费视频| 日本中文字幕一区二区高清在线| 国产精品久久久久久超碰| 亚洲人成网7777777国产| 欧美成人免费影片区二区| 抖抈短视频APP免费下载| 亚洲AV无码第一区二区三区| 兰州熟妇高潮露脸| 成 人 黄 色 网 站 18| 亚洲AV永久精品无码桃色| 免费国产成人AⅤ观看| 东北老熟女对白XXXⅩHD| 亚洲成AV人片无码迅雷下载| 免费日韩无人区码卡二卡3卡| 粗大的内捧猛烈进出视频嘿嘿视频| 亚洲AⅤ日韩久久久久久| 麻豆AV一区二区天美传媒| 成本人无码H无码动漫在线网站| 性亚洲VIDEOFREE高清极| 美女MM131爽爽爽作爱视频| 粉嫩av.一区二区三区免费| 亚洲ΑV无码一区二区三区四区| 男朋友把舌头都伸进我的嘴巴里了| 二虎进入温如玉160章小说| 亚洲成AV人在线视达达兔| 欧美多人乱大交XXXXX变态亚| 国产精品99精品无码视亚| 一区二区无码在线视频| 少妇伦子伦精品无码STYLES| 久久精品国产亚洲77777| 厨房人妻HD中文字幕69XX| 亚洲熟妇另类AV老熟女| 色欲色AV免费观看|