<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        namespace.jsJavascript的命名空間庫_javascript技巧

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 21:01:01
        文檔

        namespace.jsJavascript的命名空間庫_javascript技巧

        namespace.jsJavascript的命名空間庫_javascript技巧:github:https://github.com/hirokidaichi/namespace-js 定義Namespace對象: var Namespace 現(xiàn)在來具體看一下Namespace對象的定義,它是一個NamespaceDefinition對象。該對象是一個函數(shù)對象(NamespaceDefinition對象的構(gòu)造函數(shù),
        推薦度:
        導(dǎo)讀namespace.jsJavascript的命名空間庫_javascript技巧:github:https://github.com/hirokidaichi/namespace-js 定義Namespace對象: var Namespace 現(xiàn)在來具體看一下Namespace對象的定義,它是一個NamespaceDefinition對象。該對象是一個函數(shù)對象(NamespaceDefinition對象的構(gòu)造函數(shù),

        github:https://github.com/hirokidaichi/namespace-js
        定義Namespace對象:
        var Namespace
        現(xiàn)在來具體看一下Namespace對象的定義,它是一個NamespaceDefinition對象。該對象是一個函數(shù)對象(NamespaceDefinition對象的構(gòu)造函數(shù),如果不給參數(shù)的話就默認生成一個main的命名空間),還有三個屬性,Object,Definition,Proc。其值依次為NamespaceObjectFactory,NamespaceDefinition,createProcedure函數(shù)對象類。
        代碼如下:
        196 var createNamespace = function(fqn){
        197 return new NamespaceDefinition(
        198 NamespaceObjectFactory.create(fqn || 'main')
        199 );
        200 };
        201 merge(createNamespace, {
        202 'Object' : NamespaceObjectFactory,
        203 Definition: NamespaceDefinition,
        204 Proc : createProcedure
        205 });

        NamespaceObjectFactory:根據(jù)fqn生成NamespaceObject對象。
        NamespaceObjectFactory對象只有一個create方法,參數(shù)就是命名空間的名字(Fully Qualified Name)。該方法有一個閉包環(huán)境,該環(huán)境里有一個cache變量用于緩存所有生成的NamespaceObject對象。
        一個NamespaceObject對象包含有三個屬性,stash(記錄當(dāng)前namespace),fqn(namespace名字),proc(createProcedure對象)。方法包括:enqueue,call,valueof,merge,getStash,getExport
        代碼如下:
        74 var NamespaceObject = function _Private_Class_Of_NamespaceObject(fqn){
        75 merge(this, {
        76 stash: { CURRENT_NAMESPACE : fqn },
        77 fqn : fqn,
        78 proc : createProcedure()
        79 });
        80 };
        81 merge(NamespaceObject.prototype, {
        82 enqueue: function(context) {
        83 this.proc.next(context);
        84 },
        85 call: function(state,callback) {
        86 this.proc.call(state, callback);
        87 },
        88 valueOf: function() {
        89 return "#NamespaceObject<" + this.fqn + ">";
        90 },
        91 merge: function(obj) {
        92 merge(this.stash,obj);
        93 return this;
        94 },
        95 getStash: function() {
        96 return this.stash;
        97 },
        98 getExport: function(importName) {
        99 if (importName === '*') return this.stash;
        100
        101 var importNames = importName.split(/,/),
        102 retStash = {};
        103 for(var i = 0,l=importNames.length;i104 retStash[ importNames[i] ] = this.stash[ importNames[i] ];
        105 }
        106 return retStash;
        107 }
        108 });
        109 var NamespaceObjectFactory = (function() {
        110 var cache = {};
        111 return {
        112 create :function(fqn){
        113 _assertValidFQN(fqn);
        114 return (cache[fqn] || (cache[fqn] = new NamespaceObject(fqn)));
        115 }
        116 };
        117 })();

        NamespaceDefinition:
        該對象包括5個屬性,namespaceObject,requires,useList,stash,defineCallback。并提供了相關(guān)的方法:use,_mergeStashWithNS,loadImport,define,getStash,valueOf,apply
        該對象是namespace庫的核心,它提供了所有需要的方法。
        初始化的時候,在NamespaceObject的proc的steps隊列里追加一個函數(shù)對象,該函數(shù)將調(diào)用apply方法。
        代碼如下:
        119 var NamespaceDefinition = function _Private_Class_Of_NamespaceDefinition(nsObj) {
        120 merge(this, {
        121 namespaceObject: nsObj,
        122 requires : [],
        123 useList : [],
        124 stash : {},
        125 defineCallback : undefined
        126 });
        127 var _self = this;
        128 nsObj.enqueue(function($c){ _self.apply($c); });
        129 };
        130 merge(NamespaceDefinition.prototype, {
        131 use: function(syntax){
        132 this.useList.push(syntax);
        133 var splitted = syntax.split(/\s+/);
        134 var fqn = splitted[0];
        135 var importName = splitted[1];
        136 _assertValidFQN(fqn);
        137 this.requires.push(function($c){
        138 var context = this;
        139 var require = NamespaceObjectFactory.create(fqn);
        140 require.call(this,function(state){
        141 context.loadImport(require,importName);
        142 $c();
        143 });
        144 });
        145 return this;
        146 },
        147 _mergeStashWithNS: function(nsObj){
        148 var nsList = nsObj.fqn.split(/\./);
        149 var current = this.getStash();
        150
        151 for(var i = 0,l=nsList.length;i152 if( !current[nsList[i]] ) current[nsList[i]] = {};
        153 current = current[nsList[i]];
        154 }
        155
        156 var lastLeaf = nsList[nsList.length-1];
        157 current[lastLeaf] = merge(current[lastLeaf] || {}, nsObj.getStash());
        158 },
        159 loadImport: function(nsObj,importName){
        160 if( importName ){
        161 merge( this.stash, nsObj.getExport(importName) );
        162 }else{
        163 this._mergeStashWithNS( nsObj );
        164 }
        165 },
        166 define: function(callback){
        167 var nsDef = this, nsObj = this.namespaceObject;
        168 this.defineCallback = function($c) {
        169 var ns = {
        170 provide : function(obj){
        171 nsObj.merge(obj);
        172 $c();
        173 }
        174 };
        175 merge(ns, nsDef.getStash());
        176 merge(ns, nsObj.getStash());
        177 callback(ns);
        178 };
        179 },
        180 getStash: function(){
        181 return this.stash;
        182 },
        183 valueOf: function(){
        184 return "#NamespaceDefinition<"+this.namespaceObject+"> uses :" + this.useList.join(',');
        185 },
        186 apply: function(callback){
        187 var nsDef = this;
        188 createProcedure(nsDef.requires)
        189 .next(nsDef.defineCallback)
        190 .call(nsDef,function(){
        191 callback( nsDef.getStash() );
        192 });
        193 }
        194 });

        createProcedure:該對象是一個函數(shù)對象,返回Procedure對象的next方法的結(jié)果。
        Procedure:
        Procedure對象有三個屬性:state,steps,_status(默認為init)。提供一下幾種方法:next,isRunnig,enqueue,dequeue,call,_invoke。

        代碼如下:
        1 var Namespace = (function(){
        2 /* utility */
        3 var merge = function(target, source){ // 把source的所有自身屬性copy到target中去,并返回target對象 4 for(var p in source)
        5 if(source.hasOwnProperty( p )) target[p] = source[p];
        6 return target;
        7 };
        8 var _assertValidFQN = function(fqn){ // 驗證namespace名字的有效性,必須是小寫英數(shù)字,下劃線和點
        9 if(!(/^[a-z0-9_.]+/).test(fqn)) throw('invalid namespace');
        10 };
        11
        12 var Procedure = function _Private_Class_Of_Proc(){
        13 merge(this, {
        14 state : {}, // 狀態(tài)
        15 steps : [], // 存儲狀態(tài)的數(shù)組
        16 _status: 'init'
        17 });
        18 };
        19 merge(Procedure.prototype, {
        20 next: function(state){ // 如果state有值,存入到steps隊列隊尾,然后返回this
        21 if(state) this.enqueue(state);
        22 return this;
        23 },
        24 isRunning: function(){ // 判定是否為running狀態(tài)
        25 return (this._status === 'running');
        26 },
        27 enqueue: function(state){ // 這里其實是用數(shù)組steps來模擬隊列,enqueue就是從隊尾入隊列
        28 this.steps.push(state);
        29 },
        30 dequeue: function(){ // dequeue就是從對頭出隊列
        31 return this.steps.shift();
        32 },
        33 call: function(initialState,callback){ //
        34 if( this.isRunning() ) throw("do not run twice");
        35
        36 this.state = initialState || {}; // 保存當(dāng)前state(NamespaceDefinition對象)
        37 this.enqueue(function($c){ // 函數(shù)入隊列steps
        38 $c(); // 執(zhí)行傳進來的函數(shù)
        39 if(callback)callback(this); // 如果存在回調(diào)函數(shù)的,執(zhí)行回調(diào)函數(shù)
        40 });
        41 this._status = 'running'; // 設(shè)置狀態(tài)為running
        42 this._invoke(); // 調(diào)用_invoke
        43 },
        44 _invoke: function(){
        45 var _self = this;
        46 var step = _self.dequeue(); // 對象出隊列(FIFO)
        47 if( !step ){
        48 _self._status = 'finished'; // 如果隊列為空,則設(shè)置狀態(tài)為finished
        49 return;
        50 } // step是數(shù)組的情況下不走這條路徑
        51 if( step.call ) { // 如果該對象是函數(shù)對象的時候,則執(zhí)行該call方法,并指定內(nèi)部this為_self.state,回調(diào)函數(shù)里面繼續(xù)調(diào)用_invoke
        52 return step.call( _self.state,function _cont(state){
        53 if( state ) _self.state = state;
        54 _self._invoke();
        55 });
        56 }
        57 var finishedProcess = 0;
        58 if( step.length === 0 ) _self._invoke(); // 如果該數(shù)組長度為0,則調(diào)用_invoke
        59 for(var i =0,l=step.length;i60 step[i].call(_self.state,function _joinWait(){
        61 finishedProcess++;
        62 if( finishedProcess == l ){
        63 _self._invoke();
        64 }
        65 });
        66 }
        67 }
        68 });
        69
        70 var createProcedure = function(state) {
        71 return new Procedure().next(state);
        72 };
        73
        74 var NamespaceObject = function _Private_Class_Of_NamespaceObject(fqn){
        75 merge(this, {
        76 stash: { CURRENT_NAMESPACE : fqn },
        77 fqn : fqn,
        78 proc : createProcedure()
        79 });
        80 };
        81 merge(NamespaceObject.prototype, {
        82 enqueue: function(context) {
        83 this.proc.next(context);
        84 },
        85 call: function(state,callback) {
        86 this.proc.call(state, callback);
        87 },
        88 valueOf: function() {
        89 return "#NamespaceObject<" + this.fqn + ">";
        90 },
        91 merge: function(obj) {
        92 merge(this.stash,obj);
        93 return this;
        94 },
        95 getStash: function() {
        96 return this.stash;
        97 },
        98 getExport: function(importName) {
        99 if (importName === '*') return this.stash;
        100
        101 var importNames = importName.split(/,/),
        102 retStash = {};
        103 for(var i = 0,l=importNames.length;i104 retStash[ importNames[i] ] = this.stash[ importNames[i] ];
        105 }
        106 return retStash;
        107 }
        108 });
        109 var NamespaceObjectFactory = (function() {
        110 var cache = {};
        111 return {
        112 create :function(fqn){
        113 _assertValidFQN(fqn);
        114 return (cache[fqn] || (cache[fqn] = new NamespaceObject(fqn)));
        115 }
        116 };
        117 })();
        118
        119 var NamespaceDefinition = function _Private_Class_Of_NamespaceDefinition(nsObj) {
        120 merge(this, {
        121 namespaceObject: nsObj,
        122 requires : [],
        123 useList : [],
        124 stash : {},
        125 defineCallback : undefined
        126 });
        127 var _self = this;
        128 nsObj.enqueue(function($c){ _self.apply($c); });
        129 };
        130 merge(NamespaceDefinition.prototype, {
        131 use: function(syntax){ // 使用namespace
        132 this.useList.push(syntax); // 該namespace字符串存入數(shù)組useList
        133 var splitted = syntax.split(/\s+/); // namespace和它的對象使用空格分開
        134 var fqn = splitted[0]; // 取得namespace
        135 var importName = splitted[1]; // 取得namespace中的對象
        136 _assertValidFQN(fqn);
        137 this.requires.push(function($c){ // 放一個函數(shù)到requires數(shù)組中
        138 var context = this;
        139 var require = NamespaceObjectFactory.create(fqn); // 獲取指定的NamespaceObject對象,之前生成過得對象可以直接從緩存中獲取
        140 require.call(this,function(state){ // 調(diào)用NamespaceObject對象的call方法
        141 context.loadImport(require,importName);
        142 $c();
        143 });
        144 });
        145 return this;
        146 },
        147 _mergeStashWithNS: function(nsObj){
        148 var nsList = nsObj.fqn.split(/\./);
        149 var current = this.getStash();
        150
        151 for(var i = 0,l=nsList.length;i152 if( !current[nsList[i]] ) current[nsList[i]] = {};
        153 current = current[nsList[i]];
        154 }
        155
        156 var lastLeaf = nsList[nsList.length-1];
        157 current[lastLeaf] = merge(current[lastLeaf] || {}, nsObj.getStash());
        158 },
        159 loadImport: function(nsObj,importName){
        160 if( importName ){
        161 merge( this.stash, nsObj.getExport(importName) );
        162 }else{
        163 this._mergeStashWithNS( nsObj );
        164 }
        165 },
        166 define: function(callback){
        167 var nsDef = this, nsObj = this.namespaceObject;
        168 this.defineCallback = function($c) { // 給defineCallback賦值,同時定義一下該回調(diào)函數(shù)的上下文,nsDef和nsObj兩個對象。
        169 var ns = {
        170 provide : function(obj){
        171 nsObj.merge(obj);
        172 $c();
        173 }
        174 };
        175 merge(ns, nsDef.getStash());
        176 merge(ns, nsObj.getStash());
        177 callback(ns);
        178 };
        179 },
        180 getStash: function(){
        181 return this.stash;
        182 },
        183 valueOf: function(){
        184 return "#NamespaceDefinition<"+this.namespaceObject+"> uses :" + this.useList.join(',');
        185 },
        186 apply: function(callback){
        187 var nsDef = this;
        188 createProcedure(nsDef.requires)
        189 .next(nsDef.defineCallback)
        190 .call(nsDef,function(){
        191 callback( nsDef.getStash() );
        192 });
        193 }
        194 });
        195
        196 var createNamespace = function(fqn){
        197 return new NamespaceDefinition(
        198 NamespaceObjectFactory.create(fqn || 'main')
        199 );
        200 };
        201 merge(createNamespace, {
        202 'Object' : NamespaceObjectFactory,
        203 Definition: NamespaceDefinition,
        204 Proc : createProcedure
        205 });
        206 return createNamespace;
        207 })();

        追加定義Namespace支持的方法:
        Namespace.use
        Namespace.fromInternal
        Namespace.GET
        Namespace.fromExternal
        代碼如下:
        1 Namespace.use = function(useSyntax){ return Namespace().use(useSyntax); }
        2 Namespace.fromInternal = Namespace.GET = (function(){
        3 var get = (function(){
        4 var createRequester = function() {
        5 var xhr;
        6 try { xhr = new XMLHttpRequest() } catch(e) {
        7 try { xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {
        8 try { xhr = new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {
        9 try { xhr = new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {
        10 try { xhr = new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {
        11 throw new Error( "This browser does not support XMLHttpRequest." )
        12 }
        13 }
        14 }
        15 }
        16 }
        17 return xhr;
        18 };
        19 var isSuccessStatus = function(status) {
        20 return (status >= 200 && status < 300) ||
        21 status == 304 ||
        22 status == 1223 ||
        23 (!status && (location.protocol == "file:" || location.protocol == "chrome:") );
        24 };
        25
        26 return function(url,callback){
        27 var xhr = createRequester();
        28 xhr.open('GET',url,true);
        29 xhr.onreadystatechange = function(){
        30 if(xhr.readyState === 4){
        31 if( isSuccessStatus( xhr.status || 0 )){
        32 callback(true,xhr.responseText);
        33 }else{
        34 callback(false);
        35 }
        36 }
        37 };
        38 xhr.send('')
        39 };
        40 })();
        41
        42 return function(url,isManualProvide){
        43 return function(ns){
        44 get(url,function(isSuccess,responseText){
        45 if( isSuccess ){
        46 if( isManualProvide )
        47 return eval(responseText);
        48 else
        49 return ns.provide( eval( responseText ) );
        50 }else{
        51 var pub = {};
        52 pub[url] = 'loading error';
        53 ns.provide(pub);
        54 }
        55 });
        56 };
        57 };
        58 })();
        59
        60 Namespace.fromExternal = (function(){
        61 var callbacks = {};
        62 var createScriptElement = function(url,callback){
        63 var scriptElement = document.createElement('script');
        64
        65 scriptElement.loaded = false;
        66
        67 scriptElement.onload = function(){
        68 this.loaded = true;
        69 callback();
        70 };
        71 scriptElement.onreadystatechange = function(){
        72 if( !/^(loaded|complete)$/.test( this.readyState )) return;
        73 if( this.loaded ) return;
        74 scriptElement.loaded = true;
        75 callback();
        76 };
        77 scriptElement.src = url;
        78 document.body.appendChild( scriptElement );
        79 return scriptElement.src;
        80 };
        81 var domSrc = function(url){
        82 return function(ns){
        83 var src = createScriptElement(url,function(){
        84 var name = ns.CURRENT_NAMESPACE;
        85 var cb = callbacks[name];
        86 delete callbacks[name];
        87 cb( ns );
        88 });
        89 }
        90 };
        91 domSrc.registerCallback = function(namespace,callback) {
        92 callbacks[namespace] = callback;
        93 };
        94 return domSrc;
        95 })();
        96
        97 try{ module.exports = Namespace; }catch(e){}

        具體看一個例子:
        代碼如下:
        1 Namespace('logtest')
        2 .define(function (ns) {
        3 console.log(2);
        4 ns.provide({
        5 log : function () { console.log(3); }
        6 });
        7 });
        8
        9 console.log(4);
        10
        11 Namespace
        12 .use('logtest')
        13 .apply( function (ns) {
        14 console.log(5);
        15 ns.logtest.log();
        16 });

        1:Namespace('logtest') => new NamespaceDefinition(NamespaceObjectFactory.create('logtest'))
        即生成一個NamespaceDefinition對象,該對象是由NamespaceObject對象來初始化的,該對象同時還有三個屬性,Object,Definition,Proc。其值依次為 NamespaceObjectFactory,NamespaceDefinition,createProcedure函數(shù)對象類。Namespace('logtest') 返回的結(jié)果就是生成的NamespaceDefinition對象,然后調(diào)用其define方法,初始化defineCallback。此時僅僅是定義,不做具體的動作。

        代碼如下:
        166 define: function(callback){
        167 var nsDef = this, nsObj = this.namespaceObject;
        168 this.defineCallback = function($c) { // 給defineCallback賦值,同時定義一下該回調(diào)函數(shù)的上下文,nsDef和nsObj兩個對象。
        169 var ns = {
        170 provide : function(obj){
        171 nsObj.merge(obj);
        172 $c();
        173 }
        174 };
        175 merge(ns, nsDef.getStash());
        176 merge(ns, nsObj.getStash());
        177 callback(ns);
        178 };
        179 },

        2:使用之前定義的namespace里面的對象,Namespace.use() => Namespace().use() => Namespace('main').use()。調(diào)用use的時候初始化requires數(shù)組。

        代碼如下:
        131 use: function(syntax){ // 使用namespace
        132 this.useList.push(syntax); // 該namespace字符串存入數(shù)組useList
        133 var splitted = syntax.split(/\s+/); // namespace和它的對象使用空格分開
        134 var fqn = splitted[0]; // 取得namespace
        135 var importName = splitted[1]; // 取得namespace中的對象
        136 _assertValidFQN(fqn);
        137 this.requires.push(function($c){ // 放一個函數(shù)到requires數(shù)組中
        138 var context = this;
        139 var require = NamespaceObjectFactory.create(fqn); // 獲取指定的NamespaceObject對象,之前生成過得對象可以直接從緩存中獲取
        140 require.call(this,function(state){ // 調(diào)用NamespaceObject對象的call方法
        141 context.loadImport(require,importName);
        142 $c();
        143 });
        144 });
        145 return this;
        146 },

        3:調(diào)用main的apply方法。看一下具體的apply方法
        代碼如下:
        186 apply: function(callback){
        187 var nsDef = this;
        188 createProcedure(nsDef.requires)
        189 .next(nsDef.defineCallback)
        190 .call(nsDef,function(){
        191 callback( nsDef.getStash() );
        192 });
        193 }

        取出requires數(shù)組里面的對象生成Proc對象,并把該requires數(shù)組里的對象入隊列steps中,還有nsDef.defineCallback也入隊列(此例中為undefined),調(diào)用Proc的call方法。第一個參數(shù)是nsDef,第二個參數(shù)是回調(diào)函數(shù)。
        具體使用方法:
        在定義Namespace的時候,所有的定義放在define里面,并且以匿名函數(shù)的形式定義。function (ns) {  // 具體的實現(xiàn)  // 定義對外公開的對象,外部在use該nsName之后,就可以通過ns.nsName.key()來調(diào)用它  ns.provide({ key : value});}
        使用namespace.js的好處,所有的定義都是在需要的時候才開始執(zhí)行的,也就是在具體使用的時候才開始解析定義。

        ps:具體內(nèi)部調(diào)用關(guān)系還是沒有弄明白,今后有時間再整理,這篇太亂了。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        namespace.jsJavascript的命名空間庫_javascript技巧

        namespace.jsJavascript的命名空間庫_javascript技巧:github:https://github.com/hirokidaichi/namespace-js 定義Namespace對象: var Namespace 現(xiàn)在來具體看一下Namespace對象的定義,它是一個NamespaceDefinition對象。該對象是一個函數(shù)對象(NamespaceDefinition對象的構(gòu)造函數(shù),
        推薦度:
        標簽: js javascript js中
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 人成午夜免费大片在线观看 | 国产精品黄页在线播放免费| 久久香蕉国产线看观看亚洲片| 国产精品极品美女自在线观看免费| yy6080亚洲一级理论| 亚洲成a人片在线观看天堂无码 | 亚洲av无码专区国产乱码在线观看| 中文无码日韩欧免费视频| 情人伊人久久综合亚洲| 免费无码av片在线观看| 亚洲AV第一页国产精品| 最近免费中文字幕mv电影| 亚洲精品伊人久久久久| 免费看少妇作爱视频| 四虎精品免费永久免费视频| 亚洲一区精品无码| 午夜不卡久久精品无码免费| 亚洲国产成人久久综合一区| 永久久久免费浮力影院| 五月天国产成人AV免费观看| 亚洲国产精品无码一线岛国| 久久久久免费看成人影片| 亚洲中文字幕无码爆乳| 亚洲AV无码乱码精品国产| 国产成人精品无码免费看| 亚洲日韩乱码中文无码蜜桃| 永久免费视频v片www| 国产精品免费大片一区二区| 亚洲视频一区在线观看| 国产三级在线观看免费| 国产精品hd免费观看| 亚洲精品第一国产综合精品| 精品免费国产一区二区| 中文在线免费观看| 亚洲人成网站在线观看播放动漫| 波多野结衣一区二区免费视频| 青青操免费在线视频| 中文字幕亚洲码在线| 亚洲av综合色区| 在线播放免费播放av片| 久久国产乱子伦精品免费一|