精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

用了這么久的 require,你真的懂它的原理嗎?

開發(fā) 前端
在大多數(shù)情況下我們會(huì)在瀏覽器中去運(yùn)行javascript,有了node的出現(xiàn),我們可以在node中去運(yùn)行javascript,這意味著哪里安裝了node或者瀏覽器,我們就可以在哪里運(yùn)行javascript。

[[433835]]

 我們常說node并不是一門新的編程語言,他只是javascript的運(yùn)行時(shí),運(yùn)行時(shí)你可以簡(jiǎn)單地理解為運(yùn)行javascript的環(huán)境。在大多數(shù)情況下我們會(huì)在瀏覽器中去運(yùn)行javascript,有了node的出現(xiàn),我們可以在node中去運(yùn)行javascript,這意味著哪里安裝了node或者瀏覽器,我們就可以在哪里運(yùn)行javascript。

1.node模塊化的實(shí)現(xiàn)

node中是自帶模塊化機(jī)制的,每個(gè)文件就是一個(gè)單獨(dú)的模塊,并且它遵循的是CommonJS規(guī)范,也就是使用require的方式導(dǎo)入模塊,通過module.export的方式導(dǎo)出模塊。

node模塊的運(yùn)行機(jī)制也很簡(jiǎn)單,其實(shí)就是在每一個(gè)模塊外層包裹了一層函數(shù),有了函數(shù)的包裹就可以實(shí)現(xiàn)代碼間的作用域隔離。

你可能會(huì)說,我在寫代碼的時(shí)候并沒有包裹函數(shù)呀,是的的確如此,這一層函數(shù)是node自動(dòng)幫我們實(shí)現(xiàn)的,我們可以來測(cè)試一下。

我們新建一個(gè)js文件,在第一行打印一個(gè)并不存在的變量,比如我們這里打印window,在node中是沒有window的。

  1. console.log(window); 

通過node執(zhí)行該文件,會(huì)發(fā)現(xiàn)報(bào)錯(cuò)信息如下。(請(qǐng)使用系統(tǒng)默認(rèn)cmd執(zhí)行命令)。 

  1. (function (exports, require, module, __filename, __dirname) { console.log(window);  
  2. ReferenceError: window is not defined  
  3.     at Object.<anonymous> (/Users/choice/Desktop/node/main.js:1:75)  
  4.     at Module._compile (internal/modules/cjs/loader.js:689:30)  
  5.     at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)  
  6.     at Module.load (internal/modules/cjs/loader.js:599:32)  
  7.     at tryModuleLoad (internal/modules/cjs/loader.js:538:12)  
  8.     at Function.Module._load (internal/modules/cjs/loader.js:530:3)  
  9.     at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)  
  10.     at startup (internal/bootstrap/node.js:279:19)  
  11.     at bootstrapNodeJSCore (internal/bootstrap/node.js:752:3) 

可以看到報(bào)錯(cuò)的頂層有一個(gè)自執(zhí)行的函數(shù),, 函數(shù)中包含exports, require, module, __filename, __dirname這些我們常用的全局變量。

我在之前的《前端模塊化發(fā)展歷程》一文中介紹過。自執(zhí)行函數(shù)也是前端模塊化的實(shí)現(xiàn)方案之一,在早期前端沒有模塊化系統(tǒng)的時(shí)代,自執(zhí)行函數(shù)可以很好的解決命名空間的問題,并且模塊依賴的其他模塊都可以通過參數(shù)傳遞進(jìn)來。cmd和amd規(guī)范也都是依賴自執(zhí)行函數(shù)實(shí)現(xiàn)的。

在模塊系統(tǒng)中,每個(gè)文件就是一個(gè)模塊,每個(gè)模塊外面會(huì)自動(dòng)套一個(gè)函數(shù),并且定義了導(dǎo)出方式 module.exports或者exports,同時(shí)也定義了導(dǎo)入方式require。 

  1. let moduleA = (function() {  
  2.     module.exports = Promise 
  3.     return module.exports;  
  4. })(); 

2.require加載模塊

require依賴node中的fs模塊來加載模塊文件,fs.readFile讀取到的是一個(gè)字符串。

在javascrpt中我們可以通過eval或者new Function的方式來將一個(gè)字符串轉(zhuǎn)換成js代碼來運(yùn)行。

  •  eval 
  1. const name = 'yd' 
  2. const str = 'const a = 123; console.log(name)' 
  3. eval(str); // yd; 
  •  new Function

new Function接收的是一個(gè)要執(zhí)行的字符串,返回的是一個(gè)新的函數(shù),調(diào)用這個(gè)新的函數(shù)字符串就會(huì)執(zhí)行了。如果這個(gè)函數(shù)需要傳遞參數(shù),可以在new Function的時(shí)候依次傳入?yún)?shù),最后傳入的是要執(zhí)行的字符串。比如這里傳入?yún)?shù)b,要執(zhí)行的字符串str。 

  1. const b = 3 
  2. const str = 'let a = 1; return a + b' 
  3. const fun = new Function('b', str);  
  4. console.log(fun(b, str)); // 4 

可以看到eval和Function實(shí)例化都可以用來執(zhí)行javascript字符串,似乎他們都可以來實(shí)現(xiàn)require模塊加載。不過在node中并沒有選用他們來實(shí)現(xiàn)模塊化,原因也很簡(jiǎn)單因?yàn)樗麄兌加幸粋€(gè)致命的問題,就是都容易被不屬于他們的變量所影響。

如下str字符串中并沒有定義a,但是確可以使用上面定義的a變量,這顯然是不對(duì)的,在模塊化機(jī)制中,str字符串應(yīng)該具有自身獨(dú)立的運(yùn)行空間,自身不存在的變量是不可以直接使用的。 

  1. const a = 1 
  2. const str = 'console.log(a)' 
  3. eval(str);  
  4. const func = new Function(str);  
  5. func(); 

node存在一個(gè)vm虛擬環(huán)境的概念,用來運(yùn)行額外的js文件,他可以保證javascript執(zhí)行的獨(dú)立性,不會(huì)被外部所影響。

  •  vm 內(nèi)置模塊

雖然我們?cè)谕獠慷x了hello,但是str是一個(gè)獨(dú)立的模塊,并不在村hello變量,所以會(huì)直接報(bào)錯(cuò)。 

  1. // 引入vm模塊, 不需要安裝,node 自建模塊  
  2. const vm = require('vm');  
  3. const hello = 'yd' 
  4. const str = 'console.log(hello)' 
  5. wm.runInThisContext(str); // 報(bào)錯(cuò) 

所以node執(zhí)行javascript模塊時(shí)可以采用vm來實(shí)現(xiàn)。就可以保證模塊的獨(dú)立性了。

3.require代碼實(shí)現(xiàn)

介紹require代碼實(shí)現(xiàn)之前先來回顧兩個(gè)node模塊的用法,因?yàn)橄旅鏁?huì)用得到。

  •  path模塊

用于處理文件路徑。

basename: 基礎(chǔ)路徑, 有文件路徑就不是基礎(chǔ)路徑,基礎(chǔ)路勁是1.js

extname: 獲取擴(kuò)展名

dirname: 父級(jí)路勁

join: 拼接路徑

resolve: 當(dāng)前文件夾的絕對(duì)路徑,注意使用的時(shí)候不要在結(jié)尾添加/

__dirname: 當(dāng)前文件所在文件夾的路徑

__filename: 當(dāng)前文件的絕對(duì)路徑 

  1. const path = require('path', 's');  
  2. console.log(path.basename('1.js'));  
  3. console.log(path.extname('2.txt'));  
  4. console.log(path.dirname('2.txt'));  
  5. console.log(path.join('a/b/c', 'd/e/f')); // a/b/c/d/e/  
  6. console.log(path.resolve('2.txt')); 
  • fs模塊

用于操作文件或者文件夾,比如文件的讀寫,新增,刪除等。常用方法有readFile和readFileSync,分別是異步讀取文件和同步讀取文件。 

  1. const fs = require('fs');  
  2. const buffer = fs.readFileSync('./name.txt', 'utf8'); // 如果不傳入編碼,出來的是二進(jìn)制  
  3. console.log(buffer); 

fs.access: 判斷是否存在,node10提供的,exists方法已經(jīng)被廢棄, 原因是不符合node規(guī)范,所以我們采用access來判斷文件是否存在。 

  1. try {  
  2.     fs.accessSync('./name.txt');  
  3. } catch(e) {  
  4.     // 文件不存在  

4.手動(dòng)實(shí)現(xiàn)require模塊加載器

首先導(dǎo)入依賴的模塊path,fs, vm, 并且創(chuàng)建一個(gè)Require函數(shù),這個(gè)函數(shù)接收一個(gè)modulePath參數(shù),表示要導(dǎo)入的文件路徑。 

  1. // 導(dǎo)入依賴  
  2. const path = require('path'); // 路徑操作  
  3. const fs = require('fs'); // 文件讀取  
  4. const vm = require('vm'); // 文件執(zhí)行  
  5. // 定義導(dǎo)入類,參數(shù)為模塊路徑  
  6. function Require(modulePath) {  
  7.     ...  

在Require中獲取到模塊的絕對(duì)路徑,方便使用fs加載模塊,這里讀取模塊內(nèi)容我們使用new Module來抽象,使用tryModuleLoad來加載模塊內(nèi)容,Module和tryModuleLoad我們稍后實(shí)現(xiàn),Require的返回值應(yīng)該是模塊的內(nèi)容,也就是module.exports。 

  1. // 定義導(dǎo)入類,參數(shù)為模塊路徑  
  2. function Require(modulePath) {  
  3.     // 獲取當(dāng)前要加載的絕對(duì)路徑  
  4.     let absPathname = path.resolve(__dirname, modulePath);  
  5.     // 創(chuàng)建模塊,新建Module實(shí)例  
  6.     const module = new Module(absPathname);  
  7.     // 加載當(dāng)前模塊  
  8.     tryModuleLoad(module); 
  9.     // 返回exports對(duì)象  
  10.     return module.exports;  

Module的實(shí)現(xiàn)很簡(jiǎn)單,就是給模塊創(chuàng)建一個(gè)exports對(duì)象,tryModuleLoad執(zhí)行的時(shí)候?qū)?nèi)容加入到exports中,id就是模塊的絕對(duì)路徑。 

  1. // 定義模塊, 添加文件id標(biāo)識(shí)和exports屬性  
  2. function Module(id) {  
  3.     this.id = id;  
  4.     // 讀取到的文件內(nèi)容會(huì)放在exports中  
  5.     this.exports = {};  

之前我們說過node模塊是運(yùn)行在一個(gè)函數(shù)中,這里我們給Module掛載靜態(tài)屬性wrapper,里面定義一下這個(gè)函數(shù)的字符串,wrapper是一個(gè)數(shù)組,數(shù)組的第一個(gè)元素就是函數(shù)的參數(shù)部分,其中有exports,module. Require,__dirname, __filename, 都是我們模塊中常用的全局變量。注意這里傳入的Require參數(shù)是我們自己定義的Require。

第二個(gè)參數(shù)就是函數(shù)的結(jié)束部分。兩部分都是字符串,使用的時(shí)候我們將他們包裹在模塊的字符串外部就可以了。 

  1. Module.wrapper = [  
  2.     "(function(exports, module, Require, __dirname, __filename) {",  
  3.     "})"  

_extensions用于針對(duì)不同的模塊擴(kuò)展名使用不同的加載方式,比如JSON和javascript加載方式肯定是不同的。JSON使用JSON.parse來運(yùn)行。

javascript使用vm.runInThisContext來運(yùn)行,可以看到fs.readFileSync傳入的是module.id也就是我們Module定義時(shí)候id存儲(chǔ)的是模塊的絕對(duì)路徑,讀取到的content是一個(gè)字符串,我們使用Module.wrapper來包裹一下就相當(dāng)于在這個(gè)模塊外部又包裹了一個(gè)函數(shù),也就實(shí)現(xiàn)了私有作用域。

使用call來執(zhí)行fn函數(shù),第一個(gè)參數(shù)改變運(yùn)行的this我們傳入module.exports,后面的參數(shù)就是函數(shù)外面包裹參數(shù)exports, module, Require, __dirname, __filename 

  1. Module._extensions = {  
  2.     '.js'(module) {  
  3.         const content = fs.readFileSync(module.id, 'utf8');  
  4.         const fnStr = Module.wrapper[0] + content + Module.wrapper[1];  
  5.         const fn = vm.runInThisContext(fnStr);  
  6.         fn.call(module.exports, module.exports, module, Require,_filename,_dirname);  
  7.     },  
  8.     '.json'(module) {  
  9.         const json = fs.readFileSync(module.id, 'utf8');  
  10.         module.exports = JSON.parse(json); // 把文件的結(jié)果放在exports屬性上  
  11.     }  

tryModuleLoad函數(shù)接收的是模塊對(duì)象,通過path.extname來獲取模塊的后綴名,然后使用Module._extensions來加載模塊。 

  1. // 定義模塊加載方法  
  2. function tryModuleLoad(module) {  
  3.     // 獲取擴(kuò)展名  
  4.     const extension = path.extname(module.id);  
  5.     // 通過后綴加載當(dāng)前模塊  
  6.     Module._extensions[extension](module);  

至此Require加載機(jī)制我們基本就寫完了,我們來重新看一下。Require加載模塊的時(shí)候傳入模塊名稱,在Require方法中使用path.resolve(__dirname, modulePath)獲取到文件的絕對(duì)路徑。然后通過new Module實(shí)例化的方式創(chuàng)建module對(duì)象,將模塊的絕對(duì)路徑存儲(chǔ)在module的id屬性中,在module中創(chuàng)建exports屬性為一個(gè)json對(duì)象。

使用tryModuleLoad方法去加載模塊,tryModuleLoad中使用path.extname獲取到文件的擴(kuò)展名,然后根據(jù)擴(kuò)展名來執(zhí)行對(duì)應(yīng)的模塊加載機(jī)制。

最終將加載到的模塊掛載module.exports中。tryModuleLoad執(zhí)行完畢之后module.exports已經(jīng)存在了,直接返回就可以了。 

  1. // 導(dǎo)入依賴  
  2. const path = require('path'); // 路徑操作  
  3. const fs = require('fs'); // 文件讀取  
  4. const vm = require('vm'); // 文件執(zhí)行  
  5. // 定義導(dǎo)入類,參數(shù)為模塊路徑  
  6. function Require(modulePath) {  
  7.     // 獲取當(dāng)前要加載的絕對(duì)路徑  
  8.     let absPathname = path.resolve(__dirname, modulePath);  
  9.     // 創(chuàng)建模塊,新建Module實(shí)例  
  10.     const module = new Module(absPathname);  
  11.     // 加載當(dāng)前模塊  
  12.     tryModuleLoad(module);  
  13.     // 返回exports對(duì)象  
  14.     return module.exports;  
  15.  
  16. // 定義模塊, 添加文件id標(biāo)識(shí)和exports屬性  
  17. function Module(id) {  
  18.     this.id = id;  
  19.     // 讀取到的文件內(nèi)容會(huì)放在exports中  
  20.     this.exports = {};  
  21.  
  22. // 定義包裹模塊內(nèi)容的函數(shù)  
  23. Module.wrapper = [  
  24.     "(function(exports, module, Require, __dirname, __filename) {",  
  25.     "})"  
  26.  
  27. // 定義擴(kuò)展名,不同的擴(kuò)展名,加載方式不同,實(shí)現(xiàn)js和json  
  28. Module._extensions = {  
  29.     '.js'(module) {  
  30.         const content = fs.readFileSync(module.id, 'utf8');  
  31.         const fnStr = Module.wrapper[0] + content + Module.wrapper[1];  
  32.         const fn = vm.runInThisContext(fnStr);  
  33.         fn.call(module.exports, module.exports, module, Require,_filename,_dirname);  
  34.     },  
  35.     '.json'(module) {  
  36.         const json = fs.readFileSync(module.id, 'utf8'); 
  37.         module.exports = JSON.parse(json); // 把文件的結(jié)果放在exports屬性上  
  38.     } 
  39.  
  40. // 定義模塊加載方法  
  41. function tryModuleLoad(module) {  
  42.     // 獲取擴(kuò)展名  
  43.     const extension = path.extname(module.id);  
  44.     // 通過后綴加載當(dāng)前模塊  
  45.     Module._extensions[extension](module);  

5.給模塊添加緩存

添加緩存也比較簡(jiǎn)單,就是文件加載的時(shí)候?qū)⑽募湃刖彺嬖冢偃ゼ虞d模塊時(shí)先看緩存中是否存在,如果存在直接使用,如果不存在再去重新嘉愛,加載之后再放入緩存。 

  1. // 定義導(dǎo)入類,參數(shù)為模塊路徑  
  2. function Require(modulePath) {  
  3.     // 獲取當(dāng)前要加載的絕對(duì)路徑  
  4.     let absPathname = path.resolve(__dirname, modulePath);  
  5.     // 從緩存中讀取,如果存在,直接返回結(jié)果  
  6.     if (Module._cache[absPathname]) {  
  7.         return Module._cache[absPathname].exports;  
  8.     }  
  9.     // 嘗試加載當(dāng)前模塊  
  10.     tryModuleLoad(module);  
  11.     // 創(chuàng)建模塊,新建Module實(shí)例  
  12.     const module = new Module(absPathname);  
  13.     // 添加緩存  
  14.     Module._cache[absPathname] = module;  
  15.     // 加載當(dāng)前模塊  
  16.     tryModuleLoad(module);  
  17.     // 返回exports對(duì)象  
  18.     return module.exports;  

6.自動(dòng)補(bǔ)全路徑

自動(dòng)給模塊添加后綴名,實(shí)現(xiàn)省略后綴名加載模塊,其實(shí)也就是如果文件沒有后綴名的時(shí)候遍歷一下所有的后綴名看一下文件是否存在。 

  1. // 定義導(dǎo)入類,參數(shù)為模塊路徑  
  2. function Require(modulePath) {  
  3.     // 獲取當(dāng)前要加載的絕對(duì)路徑  
  4.     let absPathname = path.resolve(__dirname, modulePath);  
  5.     // 獲取所有后綴名  
  6.     const extNames = Object.keys(Module._extensions);  
  7.     let index = 0 
  8.     // 存儲(chǔ)原始文件路徑  
  9.     const oldPath = absPathname 
  10.     function findExt(absPathname) {  
  11.         if (index === extNames.length) {  
  12.            return throw new Error('文件不存在');  
  13.         }  
  14.         try {  
  15.             fs.accessSync(absPathname);  
  16.             return absPathname;  
  17.         } catch(e) {  
  18.             const ext = extNames[index++];  
  19.             findExt(oldPath + ext);  
  20.         }  
  21.     }  
  22.     // 遞歸追加后綴名,判斷文件是否存在  
  23.     absPathname = findExt(absPathname);  
  24.     // 從緩存中讀取,如果存在,直接返回結(jié)果  
  25.     if (Module._cache[absPathname]) {  
  26.         return Module._cache[absPathname].exports;  
  27.     }  
  28.     // 嘗試加載當(dāng)前模塊  
  29.     tryModuleLoad(module);  
  30.     // 創(chuàng)建模塊,新建Module實(shí)例  
  31.     const module = new Module(absPathname);  
  32.     // 添加緩存  
  33.     Module._cache[absPathname] = module;  
  34.     // 加載當(dāng)前模塊  
  35.     tryModuleLoad(module);  
  36.     // 返回exports對(duì)象  
  37.     return module.exports;  

7.分析實(shí)現(xiàn)步驟

  • 導(dǎo)入相關(guān)模塊,創(chuàng)建一個(gè)Require方法。
  • 抽離通過Module._load方法,用于加載模塊。
  • Module.resolveFilename 根據(jù)相對(duì)路徑,轉(zhuǎn)換成絕對(duì)路徑。
  • 緩存模塊 Module._cache,同一個(gè)模塊不要重復(fù)加載,提升性能。
  • 創(chuàng)建模塊 id: 保存的內(nèi)容是 exports = {}相當(dāng)于this。
  • 利用tryModuleLoad(module, filename) 嘗試加載模塊。
  • Module._extensions使用讀取文件。
  • Module.wrap: 把讀取到的js包裹一個(gè)函數(shù)。
  • 將拿到的字符串使用runInThisContext運(yùn)行字符串。
  • 讓字符串執(zhí)行并將this改編成exports。 

 

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2021-07-21 10:10:14

require前端代碼

2020-12-07 11:05:21

HttpClient代碼Java

2019-11-27 10:54:43

Tomcat連接數(shù)線程池

2022-01-25 12:41:31

ChromeResponse接口

2022-08-11 17:14:37

Java

2022-12-09 09:46:55

插件Lombok

2022-02-08 13:39:35

LinuxUNIX系統(tǒng)

2018-01-31 10:24:45

熱插拔原理服務(wù)器

2020-02-15 15:33:55

Python如何運(yùn)作

2020-12-01 10:18:16

RabbitMQ

2021-05-28 06:16:28

藍(lán)牙Wi-FiNFC

2018-06-08 10:12:10

Web緩存體系服務(wù)器

2019-12-04 12:33:48

程序員技術(shù)設(shè)計(jì)

2024-12-10 13:00:00

C++引用

2021-05-28 07:12:58

Mybatis面試官Java

2019-05-13 14:17:06

抓包Web安全漏洞

2017-03-21 13:53:17

運(yùn)維戴爾企業(yè)級(jí)解決方案

2020-03-30 09:22:03

AI語音技術(shù)機(jī)器視覺

2019-10-18 09:50:47

網(wǎng)絡(luò)分層模型網(wǎng)絡(luò)協(xié)議

2021-05-27 21:18:56

谷歌Fuchsia OS操作系統(tǒng)
點(diǎn)贊
收藏

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

五月婷婷欧美视频| 99精品偷自拍| 欧美夫妻性视频| 中文字幕 亚洲一区| 台湾佬中文娱乐久久久| 成人免费在线视频观看| 久久国产精品一区二区三区四区| 无码人妻精品一区二区蜜桃色欲| 伊人久久大香线| 日韩精品在线视频美女| www.污污视频| 波多视频一区| 亚洲影院理伦片| 亚洲日本理论电影| 偷拍25位美女撒尿视频在线观看| 蜜桃久久av一区| 97在线观看免费高清| 一本一本久久a久久| 精品福利一区| 欧美一区二区在线看| 欧美激情成人网| 美女日批视频在线观看| 国产精品国产自产拍高清av王其| 好吊色欧美一区二区三区四区| 在线免费观看一区二区| 欧美一级一区| 国模精品一区二区三区色天香| 国产在视频线精品视频| 米奇777超碰欧美日韩亚洲| 日韩欧美高清dvd碟片| 中文字幕天天干| 欧美精品日日操| 亚洲一二三区视频在线观看| 一区二区在线观| 国产一二三区在线视频| 97久久超碰精品国产| 91成人免费视频| 国产精品怡红院| 日本欧美大码aⅴ在线播放| 欧美在线激情视频| 日韩精品国产一区二区| 欧美精品福利| 久久99久久久久久久噜噜| 国产乱子轮xxx农村| 国产一区三区在线播放| 日韩电影大片中文字幕| 日韩成人av影院| 视频一区视频二区欧美| 91.麻豆视频| 国内av一区二区| 一区二区三区无毛| 欧美一区二区三区视频在线| 超碰在线免费av| 精品一区二区三区中文字幕视频| 在线成人免费观看| 亚洲综合123| 美女日韩一区| 精品日韩一区二区| 无码人妻精品一区二区三| 9l亚洲国产成人精品一区二三 | 国产精品国产三级国产专区51| 欧美精品videos另类| 亚洲欧美在线观看| 久久综合亚洲精品| free性m.freesex欧美| 午夜精品久久久久久久久久| 欧美 日韩 国产 高清| 在线天堂资源| 欧美日韩在线电影| 国产农村妇女精品久久| 白嫩白嫩国产精品| 精品视频在线播放免| 中文字幕第4页| 色999日韩| 久久99精品久久久久久青青91| 日本少妇吞精囗交| 久久中文在线| 91欧美精品午夜性色福利在线| 精品人妻一区二区三区麻豆91 | 摸摸摸bbb毛毛毛片| 亚洲成人tv| 午夜精品一区二区三区在线| 神马久久久久久久 | 国产一卡二卡三卡四卡| 免费一区二区| 久久五月情影视| 欧美成人aaaaⅴ片在线看| 久久精品三级| 91亚洲精品在线| 深夜福利视频一区| 亚洲欧美区自拍先锋| 人妻久久久一区二区三区| 午夜无码国产理论在线| 欧美一级精品大片| 在线 丝袜 欧美 日韩 制服| 久草精品视频| 中文字幕亚洲综合| 国产精品二区一区二区aⅴ| 日日欢夜夜爽一区| 99精品在线直播| jizz日韩| 精品国产乱码久久久久久天美 | 国产经典久久久| 无遮挡爽大片在线观看视频| 欧美日本一区二区在线观看| 麻豆短视频在线观看| 欧美残忍xxxx极端| 8090成年在线看片午夜| 99热这里只有精品9| 国产亚洲一区二区三区在线观看 | 日韩不卡av在线| 亚洲欧洲日本一区二区三区| 国产欧美 在线欧美| 日本在线视频1区| 亚洲亚洲人成综合网络| 在线看免费毛片| 精品成人影院| 4438全国成人免费| www.激情五月.com| 18涩涩午夜精品.www| 激情综合网婷婷| 久久悠悠精品综合网| 久久久精品在线| 亚洲 小说区 图片区| 99麻豆久久久国产精品免费| 一二三四中文字幕| 天堂综合在线播放| 中文字幕视频在线免费欧美日韩综合在线看 | 55夜色66夜色国产精品视频| 99久久夜色精品国产亚洲| 国产精品久久久久影院| 亚欧在线免费观看| 免费成人网www| 人人澡人人澡人人看欧美| 国产 欧美 精品| 亚洲精品成人少妇| 人妻精品久久久久中文字幕69| 欧美gvvideo网站| 国产精品男女猛烈高潮激情| 免费毛片在线| 色综合色狠狠综合色| a视频免费观看| 亚洲欧美日韩一区在线观看| 精品国产中文字幕| 国产调教在线| 亚洲美女黄色片| 国产精品一区无码| 久久久精品一品道一区| 免费观看日韩毛片| 久草精品在线| 国产成人精品免费久久久久| 九一国产在线| 欧美午夜精品一区二区三区 | 亚洲精品视频观看| 一级全黄裸体片| 狠狠综合久久| 精品国产乱码一区二区三区四区| 韩国成人二区| 亚洲三级 欧美三级| 少妇无套内谢久久久久| 国产精品久久久一本精品| 91亚洲精品久久久蜜桃借种| 外国成人激情视频| 99免费在线视频观看| 91超碰在线免费| 日韩精品免费在线视频观看| 亚洲综合图片网| 中文字幕第一区| 亚洲黄色av片| 亚洲香蕉网站| 噜噜噜噜噜久久久久久91| 亚洲伦乱视频| 久久久精品日本| 人妻少妇一区二区三区| 日本韩国一区二区三区视频| 亚洲少妇xxx| 国产成人精品亚洲777人妖| 福利视频一二区| 神马电影久久| 亚洲aa在线观看| 黄色在线网站噜噜噜| 亚洲视频一区二区三区| 一区精品在线观看| 亚洲午夜电影在线观看| 欧美激情aaa| 国产麻豆一精品一av一免费| 国产精品国产亚洲精品看不卡| 国产免费播放一区二区| 国产视频999| 波多野一区二区| 丝袜一区二区三区| 国内爆初菊对白视频| 91极品美女在线| 久久激情免费视频| 久久久久久久久97黄色工厂| 日韩av影视大全| 久久精品官网| 国产女教师bbwbbwbbw| 免费成人av| 国产精品av一区| 男女啪啪999亚洲精品| 久久久久在线观看| 91sp网站在线观看入口| 亚洲风情亚aⅴ在线发布| 黄色一区二区视频| 无码av免费一区二区三区试看| 貂蝉被到爽流白浆在线观看| 粉嫩一区二区三区性色av| 久久久久免费精品| 亚洲大片av| 婷婷视频在线播放| 精品视频亚洲| 久久久精彩视频| 日韩成人在线看| 91精品美女在线| 欧美黑人巨大xxxxx| 97国产精品免费视频| 欧美精品hd| 在线性视频日韩欧美| 后进极品白嫩翘臀在线视频| 欧美日韩精品二区第二页| 亚洲 日本 欧美 中文幕| 午夜精品久久久久久久久久| 欧美成人片在线观看| 国产精品美女久久久久久久网站| 三上悠亚ssⅰn939无码播放| 不卡一卡二卡三乱码免费网站| 涩多多在线观看| 免费在线看成人av| 男女曰b免费视频| 一区二区三区国产在线| 成年人午夜免费视频| 欧美.日韩.国产.一区.二区| 亚洲色图自拍| 欧美一级精品| 亚洲成人网上| 欧美日韩一二| 欧洲精品码一区二区三区免费看| 日韩aaa久久蜜桃av| 国产一区在线观| 久久精品福利| 久久精品日韩精品| 日韩三级av| 久久精品99久久| 欧美美女在线直播| 乱一区二区三区在线播放| 女仆av观看一区| 久久精品女人的天堂av| 日本亚洲不卡| 日本免费一区二区三区| 国产一区二区三区四区二区| 日本在线免费观看一区| 精品久久中文| 亚洲一区在线免费| 亚洲最新av| 超薄肉色丝袜足j调教99| 欧美三级乱码| 美女扒开大腿让男人桶| 红桃视频欧美| 国产九九九九九| 久久夜色精品| 91亚洲免费视频| 国产精品白丝jk白祙喷水网站| 人妻精品久久久久中文字幕69| 国产v综合v亚洲欧| 日韩av无码一区二区三区不卡 | 9.1片黄在线观看| 中文字幕人成不卡一区| 欧美色图亚洲视频| 亚洲成av人片在线| 香蕉影院在线观看| 欧美色大人视频| 国产黄色大片网站| 亚洲精品大尺度| 国产毛片av在线| 久久久精品久久久| 国产精品一区二区日韩| 日韩美女免费观看| 日韩成人免费av| 国产高清在线一区二区| 在线成人动漫av| 正在播放一区二区三区| 午夜精品影院| 日韩中文字幕二区| 国产精选一区二区三区| 久久久久久久久免费看无码| 国产欧美精品国产国产专区| 日本a级片视频| 欧美午夜精品在线| 国产免费黄色片| 日韩精品中文字幕在线观看| 男人的天堂在线视频免费观看| 欧美精品福利在线| 国产第一亚洲| 国产一区不卡在线观看| 日韩精品欧美激情一区二区| 蜜臀av色欲a片无码精品一区 | 日韩不卡的av| 久久欧美中文字幕| 99精品久久久久| 在线亚洲+欧美+日本专区| 亚洲国产精品久久久久久久| 亚洲男人天堂手机在线| 宅男网站在线免费观看| 国产精品电影观看| 黄色成人美女网站| 在线观看日本一区| 久久男女视频| 日本性生活一级片| 亚洲欧美一区二区三区极速播放 | 日本不卡123| 免费a在线观看播放| 日韩理论片在线| 波多野结衣电车| 精品偷拍一区二区三区在线看| h片在线观看网站| 国产精品视频地址| 最新国产一区| 久久成人福利视频| 国产一区二区精品在线观看| 日韩福利在线视频| 欧美日韩亚洲国产一区| 国 产 黄 色 大 片| 久久69精品久久久久久久电影好| 久久69成人| 视频一区在线免费观看| 亚洲欧美久久| 精品国产av色一区二区深夜久久 | 高潮毛片又色又爽免费| 精品国产三级a在线观看| 国产原创精品视频| 国产拍精品一二三| 青青草91久久久久久久久| www一区二区www免费| 成人h动漫精品一区二区| 免看一级a毛片一片成人不卡| 在线不卡免费欧美| 香蕉视频国产在线观看| 国产精品麻豆va在线播放| 国产一区二区观看| 男人操女人免费| 久久亚洲精品国产精品紫薇| 国产黄色片免费看| 亚洲国模精品私拍| 国产资源在线观看入口av| 国产欧美日韩在线播放| 日韩图片一区| 熟妇高潮精品一区二区三区| 午夜激情久久久| 亚洲 欧美 自拍偷拍| 欧洲一区二区视频| 国产一区二区三区四区二区| 亚洲男人天堂色| 国产精品毛片无遮挡高清| 91禁在线观看| 欧美成人合集magnet| 一区二区三区亚洲变态调教大结局 | 欧美视频福利| 第一页在线视频| 天天做天天摸天天爽国产一区 | 中文字幕欧美日韩va免费视频| 99只有精品| 男同互操gay射视频在线看| 成人性色生活片| 综合激情网五月| 亚洲桃花岛网站| 99精品视频在线免费播放| 久久久久久久久影视| bt欧美亚洲午夜电影天堂| 日韩电影在线观看一区二区| zzijzzij亚洲日本成熟少妇| 蜜桃精品视频| 啊啊啊一区二区| 国产精品人妖ts系列视频| 国产三级第一页| 91精品国产高清| 欧美码中文字幕在线| 能看毛片的网站| 欧美午夜美女看片| 菠萝菠萝蜜在线观看| 国内成+人亚洲| 美女任你摸久久| 免费在线观看一级片| 日韩精品一区二区三区第95| 色猫猫成人app| 99er在线视频| 国产亚洲va综合人人澡精品| av男人天堂av| 欧日韩不卡在线视频| 婷婷丁香综合| 国产精品无码毛片| 91精品婷婷国产综合久久| 九色porny视频在线观看| 亚洲国产日韩欧美| 成人动漫视频在线| 一区二区精品视频在线观看| 66m—66摸成人免费视频| 日韩中字在线| 国产精品无码毛片| 日韩亚洲国产中文字幕欧美|