av素人天堂_free性亚洲_久久亚洲国产视频_国产网红在线_午夜av在线播放_欧美成人精品福利网站_热99在线观看_国产在线观看免费麻豆_日本高清在线观看_亚洲免费网站观看视频

JavaScript的深拷貝和淺拷貝

來源:https://segmentfault.com/a/1190000017469386

一直想梳理下工作中經(jīng)常會用到的深拷貝的內(nèi)容,然而遍覽了許多的文章,卻發(fā)現(xiàn)對深拷貝并沒有一個通用的完美實現(xiàn)方式。因為對深拷貝的定義不同,實現(xiàn)時的edge case過多,在深拷貝的時候會出現(xiàn)循環(huán)引用等問題,導(dǎo)致JS內(nèi)部并沒有實現(xiàn)深拷貝,但是我們可以來探究一下深拷貝到底有多復(fù)雜,各種實現(xiàn)方式的優(yōu)缺點,同時參考下常用庫對其的實現(xiàn)。

引用類型

之所以會出現(xiàn)深淺拷貝的問題,實質(zhì)上是由于JS對基本類型和引用類型的處理不同?;绢愋椭傅氖呛唵蔚臄?shù)據(jù)段,而引用類型指的是一個對象,而JS不允許我們直接操作內(nèi)存中的地址,也就是不能操作對象的內(nèi)存空間,所以,我們對對象的操作都只是在操作它的引用而已。

在復(fù)制時也是一樣,如果我們復(fù)制一個基本類型的值時,會創(chuàng)建一個新值,并把它保存在新的變量的位置上。而如果我們復(fù)制一個引用類型時,同樣會把變量中的值復(fù)制一份放到新的變量空間里,但此時復(fù)制的東西并不是對象本身,而是指向該對象的指針。所以我們復(fù)制引用類型后,兩個變量其實指向同一個對象,改變其中一個對象,會影響到另外一個。

var num = 10;
var obj = {
    name: 'Nicholas'
}

var num2 = num;
var obj2 = obj;

obj.name = 'Lee';
obj2.name; // 'Lee'

 

淺拷貝

如果我們要復(fù)制對象的所有屬性都不是引用類型時,就可以使用淺拷貝,實現(xiàn)方式就是遍歷并復(fù)制,最后返回新的對象。

function shallowCopy(obj) {
    var copy = {};
    // 只復(fù)制可遍歷的屬性
    for (key in obj) {
        // 只復(fù)制本身擁有的屬性
        if (obj.hasOwnProperty(key)) {
            copy[key] = obj[key];
        }
    }
    return copy;
}

如上面所說,我們使用淺拷貝會復(fù)制所有引用對象的指針,而不是具體的值,所以使用時一定要明確自己的需求,同時,淺拷貝的實現(xiàn)也是最簡單的。

JS內(nèi)部實現(xiàn)了淺拷貝,如Object.assign(),其中第一個參數(shù)是我們最終復(fù)制的目標(biāo)對象,后面的所有參數(shù)是我們的即將復(fù)制的源對象,支持對象或數(shù)組,一般調(diào)用的方式為

var newObj = Object.assign({}, originObj);

深拷貝

如果我們需要復(fù)制一個擁有所有屬性和方法的新對象,就要用到深拷貝,JS并沒有內(nèi)置深拷貝方法,主要是因為:

  1. 深拷貝怎么定義?我們怎么處理原型?怎么區(qū)分可拷貝的對象?原生DOM/BOM對象怎么拷貝?函數(shù)是新建還是引用?這些edge case太多導(dǎo)致我們無法統(tǒng)一概念,造出大家都滿意的深拷貝方法來。
  2. 內(nèi)部循環(huán)引用怎么處理,是不是保存每個遍歷過的對象列表,每次進(jìn)行對比,然后再造一個循環(huán)引用來?這樣帶來的性能消耗可以接受嗎。

解釋一些常見的問題概念,防止有些同學(xué)不明白我們在講什么。比如循環(huán)引用:

var obj = {};
obj.b = obj;

這樣當(dāng)我們深拷貝obj對象時,就會循環(huán)的遍歷b屬性,直到棧溢出。
我們的解決方案為建立一個集合[],每次遍歷對象進(jìn)行比較,如果[]中已存在,則證明出現(xiàn)了循環(huán)引用或者相同引用,我們直接返回該對象已復(fù)制的引用即可:

let hasObj = [];
function referCopy(obj) {
    let copy = {};
    hasObj.push(obj);
    for (let i in obj) {
        if (typeof obj[i] === 'object') {
            let index = hasObj.indexOf(obj[i]);
            if (index > -1) {
                console.log('存在循環(huán)引用或?qū)傩砸昧讼嗤瑢ο?);
                // 如果已存在,證明引用了相同對象,那么無論是循環(huán)引用還是重復(fù)引用,我們返回引用就可以了
                copy[i] = hasObj[index];
            } else {
                copy[i] = referCopy(obj[i]);
            }
        } else {
            copy[i] = obj[i];
        }
    }
    return copy;
}

處理原型和區(qū)分可拷貝的對象:我們一般使用function.prototype指代原型,使用obj.__proto__指代原型鏈,使用enumerable屬性表示是否可以被for ... in等遍歷,使用hasOwnProperty來查詢是否是本身元素。在原型鏈和可遍歷屬性和自身屬性之間存在交集,但都不相等,我們應(yīng)該如何判斷哪些屬性應(yīng)該被復(fù)制呢?

函數(shù)的處理:函數(shù)擁有一些內(nèi)在屬性,但我們一般不修改這些屬性,所以函數(shù)一般直接引用其地址即可。但是擁有一些存取器屬性的函數(shù)我們怎么處理?是復(fù)制值還是復(fù)制存取描述符?

var obj = {
    age: 10,
    get age() {
        return this.age;
    },
    set age(age) {
        this.age = age;
    }
};
var obj2 = $.extend(true, {}, obj);

obj2; // {age: 10}

這個是我們想要的結(jié)果嗎?大部分場景下不是吧,比如我要復(fù)制一個已有的Vue對象。當(dāng)然我們也有解決方案:

function copy(obj) {
    var copy = {};
    for (var i in obj) {
        let desc = Object.getOwnPropertyDescriptor(obj, i);
        // 檢測是否為存取描述符
        if (desc.set || desc.get) {
            Object.defineProperty(copy, i, {
                get: desc.get,
                set: desc.set,
                configuarable: desc.configuarable,
                enumerable: true
            });
        // 否則為數(shù)據(jù)描述符,則復(fù)用下面的深拷貝方法,此處簡寫
        } else {
            copy[i] = obj[i];
        }
    }
    return copy;
}

雖然邊界條件很多,但是不同的框架和庫都對該方法進(jìn)行了實現(xiàn),只不過定義不同,實現(xiàn)方式也不同,如jQuery.extend()只復(fù)制可枚舉的屬性,不繼承原型鏈,函數(shù)復(fù)制引用,內(nèi)部循環(huán)引用不處理。而lodash實現(xiàn)的就更為優(yōu)秀,它實現(xiàn)了結(jié)構(gòu)化克隆算法
該算法的優(yōu)點是:

  1. 可以復(fù)制 RegExp 對象。
  2. 可以復(fù)制 Blob、File 以及 FileList 對象。
  3. 可以復(fù)制 ImageData 對象。CanvasPixelArray 的克隆粒度將會跟原始對象相同,并且復(fù)制出來相同的像素數(shù)據(jù)。
  4. 可以正確的復(fù)制有循環(huán)引用的對象

依然存在的缺陷是:

  1. Error 以及 Function 對象是不能被結(jié)構(gòu)化克隆算法復(fù)制的;如果你嘗試這樣子去做,這會導(dǎo)致拋出 DATA_CLONE_ERR 的異常。
  2. 企圖去克隆 DOM 節(jié)點同樣會拋出 DATA_CLONE_ERROR 異常。
  3. 對象的某些特定參數(shù)也不會被保留
    • RegExp 對象的 lastIndex 字段不會被保留
    • 屬性描述符,setters 以及 getters(以及其他類似元數(shù)據(jù)的功能)同樣不會被復(fù)制。例如,如果一個對象用屬性描述符標(biāo)記為 read-only,它將會被復(fù)制為 read-write,因為這是默認(rèn)的情況下。
    • 原形鏈上的屬性也不會被追蹤以及復(fù)制。

我們先來看看常規(guī)的深拷貝,它跟淺拷貝的區(qū)別在于,當(dāng)我們發(fā)現(xiàn)對象的屬性是引用類型時,進(jìn)行遞歸遍歷復(fù)制,直到遍歷完所有屬性:

var deepClone = function(currobj){
    if(typeof currobj !== 'object'){
        return currobj;
    }
    if(currobj instanceof Array){
        var newobj = [];
    }else{
        var newobj = {}
    }
    for(var key in currobj){
        if(typeof currobj[key] !== 'object'){
            // 不是引用類型,則復(fù)制值
            newobj[key] = currobj[key];
        }else{
            // 引用類型,則遞歸遍歷復(fù)制對象
            newobj[key] = deepClone(currobj[key])    
        }
    }
    return newobj
}

這個的主要問題就是不處理循環(huán)引用,不處理對象原型,函數(shù)依然是引用類型。上面描述過的復(fù)雜問題依然存在,可以說是最簡陋但是日常工作夠用的深拷貝方式。

另外還有一種方式是使用JSON序列化,巧妙但是限制更多:

// 調(diào)用JSON內(nèi)置方法先序列化為字符串再解析還原成對象
newObj = JSON.parse(JSON.stringify(obj));

JSON是一種表示結(jié)構(gòu)化數(shù)據(jù)的格式,只支持簡單值、對象和數(shù)組三種類型,不支持變量、函數(shù)或?qū)ο髮嵗K晕覀児ぷ髦锌梢允褂盟鉀Q常見問題,但也要注意其短板:函數(shù)會丟失,原型鏈會丟失,以及上面說到的所有缺陷。

庫實現(xiàn)

上面的兩種方式可以滿足大部分場景的需求,如果有更復(fù)雜的需求,可以自己實現(xiàn)?,F(xiàn)在我們可以看一些框架和庫的解決方案,下面拿經(jīng)典的jQuery和lodash的源碼看下,它們的優(yōu)缺點上面都說過了:

jQuery.extend()

// 進(jìn)行深度復(fù)制,如果第一個參數(shù)為true則深度復(fù)制,如果目標(biāo)對象不合法,則拋棄并重構(gòu)為{}空對象,如果只有一個參數(shù)則功能為擴(kuò)展jQuery對象
jQuery.extend = jQuery.fn.extend = function() {
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[ 0 ] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    // 第一個參數(shù)可以為true來確定進(jìn)行深度復(fù)制
    if ( typeof target === "boolean" ) {
        deep = target;

        // Skip the boolean and the target
        target = arguments[ i ] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    // 如果目標(biāo)對象不合法,則強(qiáng)行重構(gòu)為{}空對象,拋棄原有的
    if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
        target = {};
    }

    // Extend jQuery itself if only one argument is passed
    // 如果只有一個參數(shù),擴(kuò)展jQuery對象
    if ( i === length ) {
        target = this;
        i--;
    }

    for ( ; i < length; i++ ) {

        // Only deal with non-null/undefined values
        // 只處理有值的對象
        if ( ( options = arguments[ i ] ) != null ) {

            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                // 阻止最簡單形式的循環(huán)引用
                // var obj={}, obj2={a:obj}; $.extend(true, obj, obj2); 就會形成復(fù)制的對象循環(huán)引用obj
                if ( target === copy ) {
                    continue;
                }
                // 如果為深度復(fù)制,則新建[]和{}空數(shù)組或空對象,遞歸本函數(shù)進(jìn)行復(fù)制
                // Recurse if we're merging plain objects or arrays
                if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                    ( copyIsArray = Array.isArray( copy ) ) ) ) {

                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && Array.isArray( src ) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject( src ) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don't bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

lodash _.baseClone()

/**
     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
     * traversed objects.
     *
     * @private
     * @param {*} value The value to clone.
     * @param {boolean} bitmask The bitmask flags.
     *  1 - Deep clone
     *  2 - Flatten inherited properties
     *  4 - Clone symbols
     * @param {Function} [customizer] The function to customize cloning.
     * @param {string} [key] The key of `value`.
     * @param {Object} [object] The parent object of `value`.
     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
     * @returns {*} Returns the cloned value.
     */
    function baseClone(value, bitmask, customizer, key, object, stack) {
      var result,
          isDeep = bitmask & CLONE_DEEP_FLAG,
          isFlat = bitmask & CLONE_FLAT_FLAG,
          isFull = bitmask & CLONE_SYMBOLS_FLAG;

      if (customizer) {
        result = object ? customizer(value, key, object, stack) : customizer(value);
      }
      if (result !== undefined) {
        return result;
      }
      if (!isObject(value)) {
        return value;
      }
      var isArr = isArray(value);
      if (isArr) {
        result = initCloneArray(value);
        if (!isDeep) {
          return copyArray(value, result);
        }
      } else {
        var tag = getTag(value),
            isFunc = tag == funcTag || tag == genTag;

        if (isBuffer(value)) {
          return cloneBuffer(value, isDeep);
        }
        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
          result = (isFlat || isFunc) ? {} : initCloneObject(value);
          if (!isDeep) {
            return isFlat
              ? copySymbolsIn(value, baseAssignIn(result, value))
              : copySymbols(value, baseAssign(result, value));
          }
        } else {
          if (!cloneableTags[tag]) {
            return object ? value : {};
          }
          result = initCloneByTag(value, tag, baseClone, isDeep);
        }
      }
      // Check for circular references and return its corresponding clone.
      stack || (stack = new Stack);
      var stacked = stack.get(value);
      if (stacked) {
        return stacked;
      }
      stack.set(value, result);

      var keysFunc = isFull
        ? (isFlat ? getAllKeysIn : getAllKeys)
        : (isFlat ? keysIn : keys);

      var props = isArr ? undefined : keysFunc(value);
      arrayEach(props || value, function(subValue, key) {
        if (props) {
          key = subValue;
          subValue = value[key];
        }
        // Recursively populate clone (susceptible to call stack limits).
        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
      });
      return result;
    }

參考資料

  1. 知乎 JS的深拷貝和淺拷貝:?https://www.zhihu.com/questio...
  2. Javascript之深拷貝:?https://aepkill.github.io/201...
  3. js對象克隆之謎:http://b-sirius.me/2017/08/26...
  4. 知乎 JS如何完整實現(xiàn)深度Clone對象:https://www.zhihu.com/questio...
  5. github lodash源碼:https://github.com/lodash/lod...
  6. MDN 結(jié)構(gòu)化克隆算法:https://developer.mozilla.org...
  7. jQuery v3.2.1 源碼
  8. JavaScript高級程序設(shè)計 第4章(變量、作用域和內(nèi)存問題)、第20章(JSON)

 

上一篇 使用JS為網(wǎng)頁制作菜單
下一篇 CSS3 Flex 布局詳解文檔
目錄
applek

applek管理員

個人說明在個人中心里面設(shè)置

本月創(chuàng)作熱力圖

最新評論
chinacnd
chinacnd
6月26日
這個主題是怎么做到加載速度那么快的?
風(fēng)起云涌
風(fēng)起云涌
6月17日
前臺投稿現(xiàn)在有點太抽象了 希望可以弄成那種分區(qū)填寫的 標(biāo)題,內(nèi)容,圖片,目錄,標(biāo)簽,這樣的
評論于留言建議
風(fēng)起云涌
風(fēng)起云涌
6月17日
希望加個開關(guān)去掉頁腳的站點身份,還有自定義頁腳居中文字
評論于留言建議
卡卡
卡卡
5月31日
倒是放個演示地址啊
av素人天堂_free性亚洲_久久亚洲国产视频_国产网红在线_午夜av在线播放_欧美成人精品福利网站_热99在线观看_国产在线观看免费麻豆_日本高清在线观看_亚洲免费网站观看视频
中文字幕在线看视频国产欧美| 蜜桃久久久久| 国产字幕中文| 99pao成人国产永久免费视频| 一区二区视频在线| 久久中文精品| 伊人永久在线| 狠狠色综合色区| 国产成人一区二区精品非洲| 欧美日韩国产不卡| 久久精品电影| 国产在成人精品线拍偷自揄拍| 国产91久久久久| 精品久久香蕉国产线看观看gif| 亚洲大片精品永久免费| 欧美一级搡bbbb搡bbbb| 欧美日韩性视频| 欧美日韩国产123区| 欧美亚洲国产日韩2020| 久久香蕉精品| 91精品国产99| 中文字幕在线看视频国产欧美| 精品全国在线一区二区| 亚洲第一精品在线| 欧美日韩三级在线观看| 91精品无人成人www| 中文字幕伊人| 91精品国产91| av免费不卡国产观看| 亚洲一区三区在线观看| 亚洲黄色在线观看| 欧美一级欧美三级在线观看| 日韩中文在线中文网三级| 日韩视频精品在线观看| 久久精品国产91精品亚洲| 欧美日韩国产中文精品字幕自在自线| 中文字幕精品在线| 国产资源在线观看入口av| 亚洲福利在线看| 欧美不卡视频一区发布| 久久久精品日韩欧美| 精品综合久久久久| 日韩精品免费观看视频| wwww亚洲| 日韩免费视频| 亚洲娇小xxxx欧美娇小| 一区在线视频观看| 日韩在线不卡| 中文av字幕一区| 亚洲 国产 欧美 日韩| 精品网站999www| 国产欧美久久久精品影院| 精品国产31久久久久久| 成人精品国产福利| 日韩免费看网站| 国产午夜精品久久| 国产成人中文字幕| 亚洲黄色www| 久久精品在线免费观看| 一区二区在线观| 欧美一级久久久久久久久大| 在线中文字幕视频观看| 国产性一级片| 欧美日韩性视频一区二区三区| 91精品国产全国免费观看| 亚洲一区在线观看视频| 午夜国产在线| 久久91精品久久久久久秒播| 日本va欧美va精品发布| 日本黄色一区二区| 亚洲综合视频一区| 日本a口亚洲| 精品人妻一区二区免费视频| 中文字幕日韩精品在线| 一级特黄大欧美久久久| 欧美色视频一区二区三区在线观看| 国产欧美 在线欧美| 国产视频一区三区| 亚洲免费在线视频一区 二区| 欧美日韩国产综合视频在线观看| 精品视频三区| 中文在线视频| 天堂在线中文资源| 色综合久久六月婷婷中文字幕| 国产成人精品免费在线| 亚洲福利精品视频| 欧美精选午夜久久久乱码6080| 久久福利视频一区二区| 日韩亚洲一区在线| 国产黄在线看| 中文在线а√在线8| 欧美日韩一二三| 91精品久久久久久蜜臀| 中文在线视频| 日韩三级视频在线播放| 日韩三级精品电影久久久| 亚洲一区精品在线| 国产三级在线| 欧美日韩中文字幕在线视频| 丰满少妇一区| 日韩国产欧美三级| 一区精品在线播放| 一本一道久久a久久精品综合蜜臀| 国产成人精品av久久| 欧美日韩一二三| 亚洲大片精品永久免费| 亚洲狠狠婷婷综合久久久久图片| 成人福利一区| 日韩一级免费视频| 91精品网站| 亚洲福利视频在线| 91精品视频国产| 99久热re在线精彩视频| 国产视频一二区| 91精品国产91久久久久久久久| 国产视频三级在线观看播放| 国产超级va在线视频| 一区二区三区精品久久久| 成人精品视频一区| 91精品蜜臀在线一区尤物| 日韩不卡在线播放| 国产啊啊啊视频在线观看| 亚洲成年网站在线观看| 91精品国产高清91久久久久久| 日韩在线中文视频| 91精品国产91久久久久| 精品综合久久久久| 欧美日韩在线不卡一区| 中文字幕在线看视频国产欧美| 1区2区3区在线视频| 国产天堂素人系列在线视频| 丰满少妇一区| 在线国产一级| 中文在线日韩| 尤物在线精品| 一级片免费网站| 国产欧美中文在线| 国产一区久久久| 亚洲成av人片| 精品免费久久久| 久久精品久久精品亚洲人| 精品综合久久久久| 久久99精品久久久久婷婷| 日韩av不卡在线观看| 国产区在线看| 国产日韩精品在线看| 91精品国产91久久久久久青草| 精品欧美不卡一区二区在线观看| 日本a口亚洲| 日韩精品在线观看视频| 日韩亚洲不卡在线| 欧美国产综合在线V| 一区在线视频观看| 亚洲国产一区自拍| 日韩中文在线视频| 欧美日韩中文字幕一区| 国产免费久久久| 亚洲欧美中文字幕| 国产91久久久久蜜臀青青天草二| 精品一二三区视频| 欧美日韩91| 日韩三级在线播放| 欧美日韩在线不卡| 欧美日韩三级一区| 日韩一二三四区| 国产欧美日韩最新| 国产黄色网页| 欧美日韩亚洲系列| 欧美 日韩 国产 高清| 999精品网| 国产一区二中文字幕在线看| 欧美中文字幕视频在线观看| 国产成人精品综合久久久| 蜜桃精品视频| 亚洲二区自拍| 亚洲国产福利视频| 在线观看91精品国产入口| 精品国产欧美成人夜夜嗨| 视频一区三区| 亚洲欧洲日产国码av系列天堂| 视频一区中文字幕国产| 中文字幕在线看精品乱码| 亚洲免费福利视频| 91欧美日韩在线| 精品国产免费视频| 天天综合天天添夜夜添狠狠添| 蜜桃视频一日韩欧美专区| 欧美一级欧美三级在线观看| 中文字幕欧美日韩| 欧美日韩免费精品| 欧美日韩精品在线| 福利在线国产| 国产欧美日韩中文字幕| 精品欧美日韩在线| 一本大道一区二区三区| 国产在线视频一区二区| 国产亚洲人成a一在线v站| 日韩久久久精品| 日韩欧美国产成人一区二区| 国产黄在线观看| 一区二区三区四区五区视频在线观看| 久久久久久自在自线| 黄色片网站在线| 亚洲三级免费看| 欧美三级中文字幕在线观看| 欧美日韩高清| 国产超级va在线视频| 久本草在线中文字幕亚洲欧美| 亚洲理论中文字幕| 色综合久久六月婷婷中文字幕| 亚洲视频色图| 亚洲高清不卡一区| 亚洲国产一区自拍| 一区二区三区鲁丝不卡| 91精品国产经典在线观看| 天堂在线www天堂中文在线| 亚洲视频中文字幕| 日韩精品在线观看视频| 日韩欧美不卡在线| 中文亚洲免费| 国产黄色在线免费观看| 亚洲欧洲日韩精品在线| 一区二区在线视频播放| 亚洲a中文字幕| 国产日韩精品在线看| 国产又粗又猛又爽又黄91精品| 欧美日韩国产一区在线| 91精品婷婷国产综合久久竹菊| 国产不卡视频在线| 亚洲国产欧美日韩精品| 国产小视频在线观看| 一区在线视频观看| 欧美日韩国产系列| 91精品国产亚洲| 日韩精品乱码av一区二区| 最新中文字幕在线播放| 午夜一区二区三区免费| 国产欧美综合在线| 二区三区中文字幕| 91精品国产高清久久久久久| 国产欧美日韩亚洲| av中文网站| 免费高清在线一区| av免费在线观看网址| 精品久久91| 在线手机中文字幕| 日韩欧美亚洲视频| 在线日韩中文字幕| 在线综合 亚洲 欧美中文字幕| 中文字幕在线观看国产| 91精品在线国产| 亚洲欧美日本国产专区一区| 在线欧美日韩国产| 中文字幕国产欧美| 国产在线www| 91久久在线| 中文字幕精品视频| 日韩精品丝袜在线| 精品国产99久久久久久| 日韩一级在线免费观看| 午夜伦欧美伦电影理论片| 免费一级欧美在线观看视频| 欧美日韩中文字幕精品| 在线视频三区| 国产视频中文字幕在线观看| 中文字幕欧美在线| 中文字幕日韩欧美在线| 欧美一级一级性生活免费录像| 亚洲开心激情| 国产91久久久久蜜臀青青天草二| 国产成人精品综合久久久| 91亚洲国产| 在线中文免费视频| 国产99精品| 日韩va亚洲va欧洲va国产| 黄色国产网站在线播放| 久久精品在线免费观看| 午夜视频在线观看一区| 91精品在线观看视频| 亚洲丝袜一区| 99久热re在线精彩视频| 欧美专区中文字幕| 91精品免费在线观看| 中文字幕日韩精品在线| 日韩欧中文字幕| 国产欧美 在线欧美| 欧美日韩第一区日日骚| 久久精品国产91精品亚洲| 在线视频国产三级| 欧美日韩三级在线| 亚洲a级在线播放观看| 一区二区在线视频播放| 亚洲 欧美 日韩系列| 日韩国产高清一区| 韩国av一区二区| 欧美日本精品| 欧美亚洲专区| 欧美日韩三级一区| 精品国产99久久久久久| 日韩不卡中文字幕| 欧美日韩在线播放一区| 高清不卡一区二区| 欧美日韩国产亚洲一区| 日韩高清不卡在线| 日本免费看黄| 欧美日韩在线播放一区| 一区二区在线观| 欧美,日韩,国产在线| 色欧美日韩亚洲| 欧美日韩一二三| 日韩欧美久久| 中文字幕在线播放一区| 免费高清在线一区| 精品国产综合久久| 欧美在线视频第一页| 99pao成人国产永久免费视频| 亚洲第一网中文字幕| 久久麻豆视频| 久久福利视频一区二区| 国产高清精品二区| 亚洲高清在线观看一区| 精品一区二区三区中文字幕在线| 亚洲国产欧美久久| 日韩欧美一级精品久久| 欧美不卡视频一区| 欧美日韩在线综合| 欧美日韩精品欧美日韩精品| 欧美日韩中文精品| 欧美亚洲视频在线看网址| 国产精久久久久| 亚洲视频 中文字幕| av三级在线播放| 国产激情99| 欧美日韩在线观看首页| 日韩精品视频免费在线观看| 欧美日韩午夜精品| 欧美日韩精品电影| 国产精品一区二三区| 国产三级在线播放| 中文字幕精品视频在线| av手机天堂| 91精品国产调教在线观看| 91精品在线观看视频| 亚洲综合在线小说| 一本久久a久久精品亚洲| 国产欧美日韩精品高清二区综合区| av免费在线不卡| 成片免费观看| 国产资源在线观看入口av| 日韩中文在线中文网三级| www中文字幕在线观看| 91久久久久久久久| 久久香蕉一区| 精品精品久久| 国产欧美久久久精品影院| 国产绿帽一区二区三区| 日韩精品 欧美| 欧美日韩综合高清一区二区| 欧美日韩在线播放三区四区| 国产伦精品免费视频| 91精品国产91久久久久久久久| 91精品国产欧美日韩| 日韩欧美三级视频| 欧美中文字幕在线观看视频| 国产99对白在线播放| 欧美日韩在线精品成人综合网| 一级片在线免费看| 在线不卡一区二区| 欧美日韩中文字幕一区| 日韩精品视频网站| 婷婷中文字幕一区| 午夜黄色小视频| 91九色在线播放| 欧美熟妇乱码在线一区| 成人ww免费完整版在线观看| 欧美va亚洲va日韩∨a综合色| 精品国产综合久久| 不卡av免费在线| 国产日韩精品在线看| www.xxxx精品| 欧美午夜精品在线| 九一久久久久久| 在线观看免费国产成人软件| 午夜福利一区二区三区| 91精品在线观| 国产成人精品av久久| 中文字幕在线观看网址| av免费网站在线观看| 欧美日韩国产中文| 在线日韩精品视频| 高清不卡一区二区| 精品久久久网| 中文字幕乱码在线| 欧美日韩中文字幕在线视频| 91 中文字幕| 日韩 欧美 亚洲| 亚洲国产欧美日韩精品| 国产激情在线视频| 高清日韩中文字幕| 91精品国产高清|