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在线观看_国产在线观看免费麻豆_日本高清在线观看_亚洲免费网站观看视频
国产字幕中文| 国产区日韩欧美| 91精品国产调教在线观看| 国产一级一片免费播放| 国产欧美日韩精品在线| 日韩在线中文字幕| 国产三级精品在线观看| 日韩欧美99| 日韩欧美不卡在线| 一区二区日韩免费看| 黄色精品在线观看| 国产手机视频一区二区| 日韩福利视频导航| 中文字幕欧美日韩精品| 日韩精品综合在线| 精品视频在线视频| 精品一区二区在线观看视频| 精品久久在线观看| 在线资源av| 精品中文字幕在线| 久草视频观看| 欧美 中文字幕| 欧美三级中文字幕在线观看| 国产一级片在线| 视频在线一区二区| 中文不卡在线| 亚洲欧洲一区二区天堂久久| 久久91精品久久久久久秒播| 欧美日韩国产中文精品字幕自在自线| 欧美二三四区| 欧美另类专区| 久久99久久99精品中文字幕| 国产在线观看黄色| 亚洲综合欧美在线| 国产三级在线| 欧美日韩在线播放视频| 91精品免费观看| www中文字幕在线观看| 亚洲图片小说综合| 国产成人综合av| 二区三区中文字幕| 日韩va亚洲va欧洲va国产| 国产一区二中文字幕在线看| 不卡一区2区| 欧洲精品在线一区| 亚洲一区日韩精品中文字幕| 日本精品免费观看高清观看| 九九在线精品| 一本一道久久a久久精品综合蜜臀| 国产亚洲欧美中文| 色综合天天性综合| 黄色一区二区在线| 黄色资源在线观看| 久久精品不卡| 精品国产免费观看一区| 91久久大香伊蕉在人线| 国产aa精品| 亚洲乱码视频| 日韩欧美中文字幕在线视频| 日韩欧美中文字幕在线观看| 欧美高清一级片在线| 亚洲一区精品在线| 欧美日韩一区二区在线视频| lutube成人福利在线观看| 久久99蜜桃精品久久久久小说| 日韩中文字幕二区| 精品国产免费观看一区| 国产在线拍揄自揄拍| 免费看ww视频网站入口| 日韩不卡中文字幕| 欧美另类久久久品| 欧美久久一二三四区| 欧美日韩免费高清| 日韩精品在线免费播放| 欧美日韩精品高清| 精品日韩欧美| 成人a在线视频免费观看| 精品国内自产拍在线视频| 精品日韩在线播放| 欧美大片在线观看一区| 精品一性一色一乱农村| 欧美日本精品在线| 中文字幕 乱码 中文乱码91| 国产欧亚日韩视频| 在线观看国产一级片| 欧美亚洲视频在线看网址| www日韩在线观看| 久久在线91| 欧美wwww| 欧美日韩国产综合网| 在线观看91精品国产入口| 欧美日韩国产系列| 精品久久香蕉国产线看观看gif| 91精品国产综合久久香蕉的特点| 国产三级精品在线观看| 欧美成人一区二区| 欧美一级免费观看| 九九在线精品| 日韩精品综合在线| 国产亚洲二区| 中文字幕日韩高清| 精品人妻一区二区免费视频| 日本亚洲欧美天堂免费| 日韩精品视频免费在线观看| 青青久在线视频免费观看| 日韩亚洲一区在线| 中文字幕在线观看国产| 91精品综合久久久久久| 亚洲三级网站| 99在线精品视频免费观看20| 国产一区在线观看视频| 国产无遮挡在线视频免费观看| 国产农村妇女精品一二区| 精品欧美不卡一区二区在线观看| а√天堂8资源中文在线| 亚洲福利在线看| 日韩美女视频一区二区在线观看| 亚洲视频在线观看日本a| 国产xxx在线| 久久久精品免费免费| 久久精品日韩欧美| 亚洲第一视频网站| 亚洲成a人片在线www| 国产91一区| 国产 中文 字幕 日韩 在线| 欧美中文字幕第一页| 二区三区不卡不卡视频| 亚洲成av人片在线| 日韩av中文字幕一区| 日韩精品午夜| 天堂在线www天堂中文在线| 国产不卡在线| 日韩欧美亚洲国产一区| 欧美日韩久久不卡| 国产区视频在线观看| 日韩欧美中文字幕在线观看| 国产日韩电影| 欧美中文字幕精品| 欧美日韩中文字幕一区| 91精品综合久久久久久| 日韩免费不卡avV| 国产乱码在线观看| 中文国产字幕在线观看| 欧美日韩国产综合久久| 亚洲福利在线视频| 亚洲免费在线视频一区 二区| 国产视频1区2区| 欧美日韩在线视频免费观看| 国产精品视频福利一区二区| 久本草在线中文字幕亚洲欧美| 国产一区在线精品| 国产自产视频| 欧美三级在线看| 国产免费播放一区二区| 精品中文字幕在线| 久久精品在线免费观看| 香蕉视频亚洲一级| 国产欧美日韩在线播放| 国产成人一区二区精品非洲| 国产三级中文字幕| 欧美不卡视频一区| 国产亚洲短视频| 亚洲第一香蕉网| 日韩精品在线免费观看视频| 久久夜色精品国产噜噜亚洲av| 黄色一区二区在线| 91精品国产高清久久久久久| 免费国产成人看片在线| 国产福利一区二区精品秒拍| 一区二区视频国产| 久久香蕉一区| 欧美日韩亚洲不卡| 国产免费电影网站入口| 中文字幕狠狠干| 蜜桃视频中文字幕| 不卡一区二区三区视频| 欧美日韩综合在线| 中文字幕在线导航| 激情综合色综合久久| 一区二区精品区| 日韩精品在线免费观看视频| 91久久精品午夜一区二区| 大香一本蕉伊线亚洲网| 精品久久久三级| 国产欧美一级| 亚洲福利视频在线| 欧美熟妇乱码在线一区| 国产无遮挡在线视频免费观看| 91麻豆视频网站| 最新中文字幕在线播放| 日韩视频一区| 天堂√8在线中文| 国产欧美久久久精品影院| 青青久在线视频免费观看| 欧美日韩不卡在线视频| 日本不卡高清视频一区| 久久久久蜜桃| 久久久99精品久久| 亚洲羞羞网站| 日韩中文字幕网| 91精品国产自产91精品| 国产最新在线| 日韩欧美中文字幕在线观看| 91亚洲国产| 久久精品在线观看| 欧美黄页在线免费观看| 欧美日韩乱国产| 亚洲视频 中文字幕| 在线手机中文字幕| 精品日韩av一区二区| 久久精品欧美日韩精品| 国产欧美中文字幕| 欧美日韩综合在线| 欧美日韩国产不卡在线看| 欧美日韩成人综合| 国产一区不卡在线| 色猫猫国产区一区二在线视频| 午夜一区二区三区视频| 日韩欧美综合在线视频| 欧美日韩在线精品一区二区三区激情综| 日韩欧美中文字幕一区| 美国av一区二区| 欧美三级日韩在线| 午夜av一区二区| 精品久久久久久综合日本欧美| 91精品在线观看视频| 国产欧美日韩在线看| 亚州福利视频| 国产日韩综合| 欧美日韩综合高清一区二区| wwwwww国产| 日韩视频精品在线观看| 久久精品最新免费国产成人| 日韩欧美一级视频| 成人欧美亚洲| av免费在线观看网址| 91吃瓜在线观看| 久久久久久久久综合| 日韩中文字幕精品视频| 中文亚洲免费| 国产乱码在线观看| 在线观看免费国产小视频| 国产午夜精品全部视频播放| 久久夜色精品国产欧美乱极品| 日韩欧美中文字幕在线视频| 99久久精品国产成人一区二区| 精品国产网站在线观看| 亚洲乱码中文字幕| 日韩精品丝袜在线| 日韩中文字幕在线观看视频| 日韩精品中文在线观看| 中文字幕在线高清| 99久久精品国产亚洲| 国产无遮挡在线视频免费观看| 日韩在线精品视频| 日韩欧美中文在线| 欧美日韩精品在线播放| 一区二区三区鲁丝不卡| 国产一区精品在线| 国产日韩中文在线| 国内激情久久| 日韩精品久久久| 日韩中文字幕综合| 欧美高清一级片在线| 亚洲 国产 欧美 日韩| 高清中文字幕在线| 日韩中文字幕观看| 中文精品视频| 91精品国产丝袜白色高跟鞋| 亚洲成在线观看| 亚洲一区资源| 日韩美女视频一区二区在线观看| 国产91久久久久蜜臀青青天草二| 中文字幕精品在线| 亚洲国产午夜精品| 亚洲 欧美 中文字幕| 在线视频不卡国产V| 日韩.欧美.亚洲| 在线资源av| 日韩精品中文字幕第1页| 91精品国产91久久久久青草| 中文字幕在线欧美| 精品成人久久久| 久久久久黄色| 亚洲 欧美综合在线网络| 91精品国产高清91久久久久久| 久久久水蜜桃| 亚洲综合在线中文字幕| 免费在线视频一区二区| 日韩欧美一级视频| 伊人精品视频| 欧美日韩三级在线观看| 日本a级黄色| 色猫猫国产区一区二在线视频| 97国产视频| 91麻豆免费视频网站| 三级网站免费观看| 91精品国产91综合久久蜜臀| 欧美日韩激情在线一区二区三区| 国产三级精品在线观看| 欧美日韩日本视频| 精品久久久网| 婷婷久久综合九色国产成人| 欧美国产一区视频在线观看| 一区三区视频| 视频一区二区中文字幕| 欧美久久在线观看| 在线国产一级| 亚洲va久久久噜噜噜久久| 婷婷中文字幕一区三区| 日韩免费视频一区二区| 亚洲视频在线观看三级| 久久99精品久久久久久青青日本| 亚洲一区在线观看网站| 91精品国产色综合久久不卡蜜臀| 天堂√8在线中文| 刘玥91精选国产在线观看| 日韩av在线中文字幕| 天堂精品高清1区2区3区| 被陌生人带去卫生间啪到腿软| 日韩久久精品视频| 久久中文精品| 精品国产欧美日韩| 香蕉精品久久| 国产日韩精品久久久| 欧美日韩在线播放三区四区| 欧美中文字幕第一页| 美女免费视频一区| 国产91大片| 国产一级视频在线播放| 香蕉视频亚洲一级| 91精品国产91久久久久久不卡| 日韩国产成人精品| 国产高清在线观看| 国产精品一区二区三区免费观看| 91精品久久久久久久久| 欧美日韩视频免费播放| 国产成人精品三级| 亚洲综合欧美在线| 中文字幕在线中文字幕二区| 日韩视频精品在线观看| 91麻豆免费视频网站| 国产欧美日韩久久| 日韩专区中文字幕| 刘玥91精选国产在线观看| 精品精品久久| 99久久精品国产亚洲| 久久久久久91| 日韩国产欧美三级| 国产裸舞福利在线视频合集| 热久久精品国产| 中文在线а√在线8| 在线手机中文字幕| 中文av字幕一区| 国产卡1卡2卡三卡在线| 亚洲尤物av| 日韩精品在线中文字幕| 久久久久久久久99精品| 国产黄色片中文字幕| 在线欧美一级视频| 欧美中文字幕精品| 在线日韩中文字幕| 国产日韩av一区| 日韩国产成人精品| 久久久久久久久99精品| 亚洲欧美中文字幕在线一区| 欧美日韩国产高清视频| 91麻豆精品在线| 中文字幕欧美人妻精品一区蜜臀| 日韩欧美在线精品| 日韩欧美中文字幕公布| 99日韩精品| 国产一级片在线播放| 天堂√8在线中文| 亚洲一区日韩在线| 日韩欧美不卡在线| 欧美va亚洲va日韩∨a综合色| 日韩精品免费观看视频| 日韩中文字幕网| 亚洲制服一区| 国产一级视频| 在线观看免费国产成人软件| 一区二区三区高清在线| 欧美亚洲国产日韩2020| 中文字幕欧美日韩在线| 日韩中文欧美在线| 欧美日韩高清一区二区| 欧美日韩999| 欧美中文字幕| 欧美一级手机免费观看片| 国产欧美久久久| 国产一卡2卡3卡四卡网站| 国产在线观看91| 国产一卡2卡3卡免费网站| 欧美日韩精品是欧美日韩精品| 亚洲视频色图| 精品一区二区三区中文字幕在线| 日韩欧美中文字幕视频| 欧美日韩精品高清| 日韩精品免费视频一区二区三区|