欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承

今天就跟大家聊聊有關(guān)如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)公司企業(yè)建站,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),專注于網(wǎng)站建設(shè)技術(shù),精于網(wǎng)頁(yè)設(shè)計(jì),有多年建站和網(wǎng)站代運(yùn)營(yíng)經(jīng)驗(yàn),設(shè)計(jì)師為客戶打造網(wǎng)絡(luò)企業(yè)風(fēng)格,提供周到的建站售前咨詢和貼心的售后服務(wù)。對(duì)于成都做網(wǎng)站、網(wǎng)站制作中不同領(lǐng)域進(jìn)行深入了解和探索,創(chuàng)新互聯(lián)在網(wǎng)站建設(shè)中充分了解客戶行業(yè)的需求,以靈動(dòng)的思維在網(wǎng)頁(yè)中充分展現(xiàn),通過(guò)對(duì)客戶行業(yè)精準(zhǔn)市場(chǎng)調(diào)研,為客戶提供的解決方案。

其實(shí),無(wú)論是寫(xiě)什么語(yǔ)言的程序員,最終的目的,都是把產(chǎn)品或代碼封裝到一起,提供接口,讓使用者很舒適的實(shí)現(xiàn)功能。所以對(duì)于我來(lái)說(shuō),往往頭疼的不是寫(xiě)代碼,而是寫(xiě)注釋和文檔!如果接口很亂,肯定會(huì)頭疼一整天。

JavaScript 最初是以 Web 腳本語(yǔ)言面向大眾的,盡管現(xiàn)在出了服務(wù)器端的 nodejs,但是單線程的性質(zhì)還沒(méi)有變。對(duì)于一個(gè) Web  開(kāi)發(fā)人員來(lái)說(shuō),能寫(xiě)一手漂亮的組件極為重要。GitHub 上那些開(kāi)源且 stars 過(guò)百的 Web 項(xiàng)目或組件,可讀性肯定非常好。

從一個(gè)例子來(lái)學(xué)習(xí)寫(xiě)組件

組件教程的參考來(lái)自于 GitHub 上,通俗易懂,鏈接。

要實(shí)現(xiàn)下面這個(gè)功能,對(duì)一個(gè) input 輸入框的內(nèi)容進(jìn)行驗(yàn)證,只有純數(shù)字和字母的組合才是被接受的,其他都返回 failed:

如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承

全局變量寫(xiě)法

這種寫(xiě)法完全沒(méi)有約束,基本所有人都會(huì),完全沒(méi)啥技巧:

// html <input type="text" id="input"/> // javascript var input = document.getElementById("input"); function getValue(){   return input.value; } function render(){   var value = getValue();   if(!document.getElementById("show")){     var append = document.createElement('span');     append.setAttribute("id""show");     input.parentNode.appendChild(append);   }   var show = document.getElementById("show");   if(/^[0-9a-zA-Z]+$/.exec(value)){     show.innerHTML = 'Pass!';   }else{     show.innerHTML = 'Failed!';   } } input.addEventListener('keyup'function(){   render(); });

缺點(diǎn)自然不用多說(shuō),變量沒(méi)有任何隔離,嚴(yán)重污染全局變量,雖然可以達(dá)到目的,但極不推薦這種寫(xiě)法。

對(duì)象隔離作用域

鑒于以上寫(xiě)法的弊端,我們用對(duì)象來(lái)隔離變量和函數(shù):

var obj = {   input: null,   // 初始化并提供入口調(diào)用方法   init: function(config){     this.input = document.getElementById(config.id);     this.bind();     //鏈?zhǔn)秸{(diào)用     return this;   },   // 綁定   bind: function(){     var self = this;     this.input.addEventListener('keyup'function(){       self.render();     });   },   getValue: function(){     return this.input.value;   },   render: function(){     var value = this.getValue();     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id""show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   } } window.onload = function(){   obj.init({id: "input"}); }

相對(duì)于開(kāi)放式的寫(xiě)法,上面的這個(gè)方法就比較清晰了。有初始化,有內(nèi)部函數(shù)和變量,還提供入口調(diào)用方法。

新手能實(shí)現(xiàn)上面的方法已經(jīng)很不錯(cuò)了,還記得當(dāng)初做百度前端學(xué)院題目的時(shí)候,基本就是用對(duì)象了。

不過(guò)這種方法仍然有弊端。obj  對(duì)象中的方法都是公開(kāi)的,并不是私有的,其他人寫(xiě)的代碼可以隨意更改這些內(nèi)容。當(dāng)多人協(xié)作或代碼量很多時(shí),又會(huì)產(chǎn)生一系列問(wèn)題。

函數(shù)閉包的寫(xiě)法

var fun = (function(){   var _bind = function(obj){     obj.input.addEventListener('keyup'function(){       obj.render();     });   }   var _getValue = function(obj){     return obj.input.value;   }   var InputFun = function(config){};   InputFun.prototype.init = function(config){     this.input = document.getElementById(config.id);     _bind(this);     return this;   }   InputFun.prototype.render = function(){     var value = _getValue(this);     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id""show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   }   return InputFun; })(); window.onload = function(){   new fun().init({id'input'}); }

函數(shù)閉包寫(xiě)法的好處都在自執(zhí)行的閉包里,不會(huì)受到外面的影響,而且提供給外面的方法包括 init 和 render。比如我們可以像 JQuery  那樣,稍微對(duì)其改造一下:

var $ = function(id){   // 這樣子就不用每次都 new 了   return new fun().init({'id': id}); } window.onload = function(){   $('input'); }

還沒(méi)有涉及到原型,只是簡(jiǎn)單的閉包。

基本上,這已經(jīng)是一個(gè)合格的寫(xiě)法了。

面向?qū)ο?/strong>

雖然上面的方法以及夠好了,但是我們的目的,是為了使用面向?qū)ο?。面向?qū)ο笠恢币詠?lái)都是被認(rèn)為***的編程方式,如果每個(gè)人的代碼風(fēng)格都相似,維護(hù)、查看起來(lái)就非常的方便。

但是,我想在介紹面向?qū)ο笾?,先?lái)回憶一下 JS 中的繼承(實(shí)現(xiàn)我們放到***再說(shuō))。

入門(mén)級(jí)的面向?qū)ο?/strong>

提到繼承,我首先想到的就是用 new 來(lái)實(shí)現(xiàn)。還是以例子為主吧,人->學(xué)生->小學(xué)生,在 JS 中有原型鏈這么一說(shuō),__proto__ 和  prototype ,對(duì)于原型鏈就不過(guò)多闡述,如果不懂的可以自己去查閱一些資料。

在這里,我還是要說(shuō)明一下 JS 中的 new 構(gòu)造,比如 var student = new Person(name),實(shí)際上有三步操作:

var student = {}; student.__proto__ = Person.prototypePerson.call(student, name)

得到的 student 是一個(gè)對(duì)象,__proto__執(zhí)行 Person 的 prototype,Person.call 相當(dāng)于  constructor。

function Person(name){   this.name = name; } Person.prototype.Say = function(){   console.log(this.name + ' can say!'); } var ming = new Person("xiaoming"); console.log(ming.__proto__ == Person.prototype//true new的第二步結(jié)果 console.log(ming.name) // 'xiaoming' new 的第三步結(jié)果 ming.Say() // 'xiaoming can say!' proto 向上追溯的結(jié)果

利用 __proto__ 屬性的向上追溯,可以實(shí)現(xiàn)一個(gè)基于原型鏈的繼承。

function Person(name){   this.name = name; } Person.prototype.Say = function(){   console.log(this.name + ' can say!'); } function Student(name){   Person.call(this, name); //Person 的屬性賦值給 Student } Student.prototype = new Person(); //順序不能反,要在最前面 Student.prototype.DoHomeWork = function(){   console.log(this.name + ' can do homework!'); } var ming = new Student("xiaoming"); ming.DoHomeWork(); //'xiaoming can do homework!' ming.Say(); //'xiaoming can say!'

大概剛認(rèn)識(shí)原型鏈的時(shí)候,我也就只能寫(xiě)出這樣的水平了,我之前的文章。

打開(kāi)調(diào)試工具,看一下 ming 都有哪些東西:

ming   name"xiaoming"   __proto__Person     DoHomeWork: ()     nameundefined //注意這里多了一個(gè) name 屬性     __proto__: Object       Say: ()       constructor: Person(name)       __proto__: Object

當(dāng)調(diào)用 ming.Say() 的時(shí)候,剛好 ming.__proto__.__proto__ 有這個(gè)屬性,這就是鏈?zhǔn)秸{(diào)用的原理,一層一層向下尋找。

這就是最簡(jiǎn)單的繼承了。

面向?qū)ο蟮倪M(jìn)階

來(lái)看一看剛才那種做法的弊端。

  1. 沒(méi)有實(shí)現(xiàn)傳統(tǒng)面向?qū)ο笤撚械?super 方法來(lái)調(diào)用父類方法,鏈?zhǔn)胶?super 方法相比還是有一定缺陷的;

  2. 造成過(guò)多的原型屬性(name),constructor 丟失(constructor 是一個(gè)非常重要的屬性,MDN)。

因?yàn)殒準(zhǔn)绞且粚訉酉蛏蠈ふ遥勒业綖橹?,很明顯 super 直接調(diào)用父類更具有優(yōu)勢(shì)。

// 多了原型屬性 console.log(ming.__proto__) // {name: undefined}

為什么會(huì)多一個(gè) name,原因是因?yàn)槲覀儓?zhí)行了 Student.prototype = new Person();,而 new 的第三步會(huì)執(zhí)行一個(gè)  call 的函數(shù),會(huì)使得 Student.prototype.name = undefined,恰好 ming.__proto__ 指向 Student 的  prototype,用了 new 是無(wú)法避免的。

// 少了 constructor  console.log(ming.constructor == Person) //true  console.log(ming.constructor == Student) // false

這也很奇怪,明明 ming 是繼承與 Student,卻返回 false,究其原因,Student.prototype 的 constructor  方法丟失,向上找到了Student.prototype.__proto__ 的 constructor 方法。

如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承

再找原因,這句話導(dǎo)致了 Student.prototype 的 constructor 方法丟失:

Student.prototype = new Person();

在這句話之前打一個(gè)斷點(diǎn),曾經(jīng)是有的,只是被替換掉了:

如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承

找到了問(wèn)題所在,現(xiàn)在來(lái)改進(jìn):

// fn 用來(lái)排除多余的屬性(name) var fn = function(){}; fn.prototype = Person.prototype; Student.prototype = new fn(); // 重新添上 constructor 屬性 Student.prototype.constructor = Student;

用上面的繼承代碼替換掉之前的 Student.prototype = new Person();

面向?qū)ο蟮姆庋b

我們不能每一次寫(xiě)代碼的時(shí)候都這樣寫(xiě)這么多行來(lái)繼承吧,所以,于情于理,還是來(lái)進(jìn)行簡(jiǎn)單的包裝:

function classInherit(subClass, parentClass){   var fn = function(){};   fn.prototype = parentClass.prototype;   subClass.prototype = new fn();   subClass.prototype.constructor = subClass; } classInherit(StudentPerson);

哈哈,所謂的包裝,就是重抄一下代碼。

進(jìn)一步完善面向?qū)ο?/strong>

上面的問(wèn)題只是簡(jiǎn)單的解決了多余屬性和 constructor 丟失的問(wèn)題,而 supper 問(wèn)題仍然沒(méi)有改進(jìn)。

舉個(gè)栗子,來(lái)看看 supper 的重要,每個(gè)人都會(huì)睡覺(jué),sleep 函數(shù)是人的一個(gè)屬性,學(xué)生分為小學(xué)生和大學(xué)生,小學(xué)生晚上 9 點(diǎn)睡覺(jué),大學(xué)生 12  點(diǎn)睡覺(jué),于是:

Person.prototype.Sleep = function(){   console.log('Sleep!'); } function E_Student(){}; //小學(xué)生 function C_Student(){}; //大學(xué)生 classInherit(E_Student, Person); classInherit(C_Student, Person); //重寫(xiě) Sleep 方法 E_Student.prototype.Sleep = function(){   console.log('Sleep!');   console.log('Sleep at 9 clock'); } C_Student.prototype.Sleep = function(){   console.log('Sleep!');   console.log('Sleep at 12 clock'); }

對(duì)于 Sleep 方法,顯得比較混亂,而我們想要通過(guò) supper,直接調(diào)用父類的函數(shù):

E_Student.prototype.Sleep = function(){   this._supper(); //supper 方法   console.log('Sleep at 9 clock'); } C_Student.prototype.Sleep = function(){   this._supper(); //supper 方法   console.log('Sleep at 12 clock'); }

不知道對(duì) supper 的理解正不正確,總感覺(jué)怪怪的,歡迎指正!

來(lái)看下 JQuery 之父是如何 class 的面向?qū)ο螅脑谶@,源碼如下。

/* Simple JavaScript Inheritance  * By John Resig http://ejohn.org/  * MIT Licensed.  */ // Inspired by base2 and Prototype (function(){   // initializing 開(kāi)關(guān)很巧妙的來(lái)實(shí)現(xiàn)調(diào)用原型而不構(gòu)造,還有回掉   var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;   // The base Class implementation (does nothing)   // 全局,this 指向 window,***的父類   this.Class = function(){};     // Create a new Class that inherits from this class   // 繼承的入口   Class.extend = function(prop) {     //保留當(dāng)前類,一般是父類的原型     var _super = this.prototype;         // Instantiate a base class (but only create the instance,     // don't run the init constructor)     //開(kāi)關(guān) 用來(lái)使原型賦值時(shí)不調(diào)用真正的構(gòu)成流程     initializing = true;     var prototype = new this();     initializing = false;         // Copy the properties over onto the new prototype     for (var name in prop) {       // Check if we're overwriting an existing function       //對(duì)函數(shù)判斷,將屬性套到子類上       prototype[name] = typeof prop[name] == "function" &&         typeof _super[name] == "function" && fnTest.test(prop[name]) ?         (function(name, fn){           //用閉包來(lái)存儲(chǔ)           return function() {             var tmp = this._super;                         // Add a new ._super() method that is the same method             // but on the super-class             this._super = _super[name];                         // The method only need to be bound temporarily, so we             // remove it when we're done executing             //實(shí)現(xiàn)同名調(diào)用             var ret = fn.apply(this, arguments);               this._super = tmp;             return ret;           };         })(name, prop[name]) :         prop[name];     }         // 要返回的子類     function Class() {       // All construction is actually done in the init method       if ( !initializing && this.init )         this.init.apply(this, arguments);     }     //前面介紹過(guò)的,繼承     Class.prototype = prototype;         Class.prototype.constructor = Class;       Class.extend = arguments.callee;         return Class;   }; })();

這個(gè)時(shí)候就可以很輕松的實(shí)現(xiàn)面向?qū)ο螅褂萌缦拢?/p>

var Person = Class.extend({   initfunction(name){     this.name = name;   },   Sayfunction(name){     console.log(this.name + ' can Say!');   },   Sleepfunction(){     console.log(this.name + ' can Sleep!');   } }); var Student = Person.extend({   initfunction(name){     this._super('Student-' + name);   },   Sleepfunction(){     this._super();     console.log('And sleep early!');   },   DoHomeWorkfunction(){     console.log(this.name + ' can do homework!');   } }); var p = new Person('Li'); p.Say(); //'Li can Say!' p.Sleep(); //'Li can Sleep!' var ming = new Student('xiaoming'); ming.Say(); //'Student-xiaoming can Say!' ming.Sleep();//'Student-xiaoming can Sleep!'             // 'And sleep early!' ming.DoHomeWork(); //'Student-xiaoming can do homework!'

除了 John Resig 的 supper 方法,很多人都做了嘗試,不過(guò)我覺(jué)得 John Resig 的實(shí)現(xiàn)方式非常的妙,也比較貼近 supper  方法,我本人也用源碼調(diào)試了好幾個(gè)小時(shí),才勉強(qiáng)能理解。John Resig 的頭腦真是令人佩服。

ES6 中的 class

在 JS 中,class 從一開(kāi)始就屬于關(guān)鍵字,在 ES6 終于可以使用 class 來(lái)定義類。比如:

class Point {   constructor(x, y){     this.x = x;     this.y = y;   }   toString(){     return '(' + this.x + ',' + this.y + ')';   } } var p = new Point(34); console.log(p.toString()); //'(3,4)'

更多有關(guān)于 ES6 中類的使用請(qǐng)參考阮一峰老師的 Class基本語(yǔ)法。

其實(shí) ES6 中的 class 只是寫(xiě)對(duì)象原型的時(shí)候更方便,更像面向?qū)ο?,class 的功能 ES5 完全可以做到,比如就上面的例子:

typeof Point; //'function' Point.prototype; /* |Object |--> constructor: function (x, y) |--> toString: function() |--> __proto__: Object */

和用 ES5 實(shí)現(xiàn)的真的沒(méi)有什么差別,反而現(xiàn)在流行的一些庫(kù)比 ES6 的 class 能帶來(lái)更好的效益。

回到最開(kāi)始的組件問(wèn)題

那么,說(shuō)了這么多面向?qū)ο?,現(xiàn)在回到最開(kāi)始的那個(gè)組件的實(shí)現(xiàn)&mdash;&mdash;如何用面向?qū)ο髞?lái)實(shí)現(xiàn)。

還是利用 John Resig 構(gòu)造 class 的方法:

var JudgeInput = Class.extend({   initfunction(config){     this.input = document.getElementById(config.id);     this._bind();   },   _getValuefunction(){     return this.input.value;   },   _renderfunction(){     var value = this._getValue();     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id""show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   },   _bindfunction(){     var self = this;     self.input.addEventListener('keyup'function(){       self._render();     });   } }); window.onload = function(){   new JudgeInput({id"input"}); }

但是,這樣子,基本功能算是實(shí)現(xiàn)了,關(guān)鍵是不好擴(kuò)展,沒(méi)有面向?qū)ο蟮木?。所以,針?duì)目前的情況,我們準(zhǔn)備建立一個(gè) Base 基類,init  表示初始化,render 函數(shù)表示渲染,bind 函數(shù)表示綁定,destory 用來(lái)銷毀,同時(shí) get、set 方法提供獲得和更改屬性:

var Base = Class.extend({   initfunction(config){     this._config = config;     this.bind();   },   getfunction(key){     return this._config[key];   },   setfunction(key, value){     this._config[key] = value;   },   bindfunction(){     //以后構(gòu)造   },   render: function(){     //以后構(gòu)造   },   destory: function(){     //定義銷毀方法   } });

基于這個(gè) Base,我們修改 JudgeInput 如下:

var JudgeInput = Base.extend({   _getValuefunction(){     return this.get('input').value;   },   bindfunction(){     var self = this;     self.get('input').addEventListener('keyup'function(){       self.render();     });   },   renderfunction(){     var value = this._getValue();     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id""show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   } }); window.onload = function(){   new JudgeInput({inputdocument.getElementById("input")}); }

比如,我們后期修改了判斷條件,只有當(dāng)長(zhǎng)度為 5-10 的時(shí)候才會(huì)返回 success,這個(gè)時(shí)候能很快定位到 JudgeInput 的 render  函數(shù):

renderfunction(){   var value = this._getValue();   if(!document.getElementById("show")){     var append = document.createElement('span');     append.setAttribute("id""show");     input.parentNode.appendChild(append);   }   var show = document.getElementById("show");   //修改正則即可   if(/^[0-9a-zA-Z]{5,10}$/.exec(value)){     show.innerHTML = 'Pass!';   }else{     show.innerHTML = 'Failed!';   } }

以我目前的能力,只能理解到這里了。

關(guān)于一個(gè)組件的寫(xiě)法,從入門(mén)級(jí)到最終版本,一波三折,不僅要考慮代碼的實(shí)用性,還要兼顧后期維護(hù)。JS 中實(shí)現(xiàn)面向?qū)ο螅瑒偨佑| JS  的時(shí)候,我能用簡(jiǎn)單的原型鏈來(lái)實(shí)現(xiàn),后來(lái)看了一些文章,發(fā)現(xiàn)了不少問(wèn)題,在看 John Resig 的 Class,感觸頗深。還好,現(xiàn)在目的是實(shí)現(xiàn)了。

看完上述內(nèi)容,你們對(duì)如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

網(wǎng)頁(yè)名稱:如何從一個(gè)組件的實(shí)現(xiàn)來(lái)深刻理解JS中的繼承
文章路徑:http://chinadenli.net/article46/gpcseg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站設(shè)計(jì)公司、靜態(tài)網(wǎng)站、電子商務(wù)、網(wǎng)站營(yíng)銷、網(wǎng)頁(yè)設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

国产内射在线激情一区| 国产午夜精品久久福利| 日本和亚洲的香蕉视频| 亚洲乱码av中文一区二区三区| 欧美日韩综合综合久久久| 日本高清加勒比免费在线| 91老熟妇嗷嗷叫太91| 亚洲成人精品免费在线观看| 欧美熟妇喷浆一区二区| 精品国产亚洲av久一区二区三区| 亚洲欧美日韩国产自拍| 日韩特级黄片免费在线观看| 欧美一区二区不卡专区| 国产超碰在线观看免费| 91亚洲人人在字幕国产| 欧美熟妇一区二区在线| 高清一区二区三区四区五区| 日本一区二区三区黄色| 日本午夜一本久久久综合| 九九热精彩视频在线免费| 日本一本在线免费福利| 日本深夜福利视频在线| 最新日韩精品一推荐日韩精品| 91日韩在线观看你懂的| 日韩欧美第一页在线观看| 亚洲一区二区三区日韩91| 成人区人妻精品一区二区三区| 色偷偷偷拍视频在线观看| 欧美日韩国产精品黄片| 国产福利一区二区三区四区| 日韩一区二区三区四区乱码视频| 国产精品第一香蕉视频| 日本加勒比在线播放一区| 婷婷九月在线中文字幕| 国产午夜精品福利免费不| 国产精品午夜一区二区三区| 在线观看免费午夜福利| 日本不卡在线视频中文国产| 东京热加勒比一区二区| 国产伦精品一一区二区三区高清版| 91精品国产品国语在线不卡|