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ū)ο髮嵗?。所以我們工作中可以使用它解決常見問題,但也要注意其短板:函數(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ù)則功能為擴展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)對象不合法,則強行重構(gòu)為{}空對象,拋棄原有的
    if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
        target = {};
    }

    // Extend jQuery itself if only one argument is passed
    // 如果只有一個參數(shù),擴展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)

 

THE END
av素人天堂_free性亚洲_久久亚洲国产视频_国产网红在线_午夜av在线播放_欧美成人精品福利网站_热99在线观看_国产在线观看免费麻豆_日本高清在线观看_亚洲免费网站观看视频
91精品国产色综合久久不卡蜜臀| 中文字幕在线中文字幕二区| 日韩av在线中文字幕| 国产一卡二卡3卡4卡四卡在线| 久久91精品久久久久久秒播| 黄色片免费在线| 日韩欧美专区在线| 精品日韩av| 精品视频999| 日韩欧美看国产| 国产欧美日产一区| 欧美日韩性视频在线| 欧美日韩在线看| 国产成人精品av久久| 91久久久精品| 日韩精品资源二区在线| wwwwww国产| 中文 欧美 日韩| 91精品国产综合久久香蕉的特点| 日韩中文字幕在线一区| 国产 欧美在线| 欧美日韩高清在线一区| 99精品电影| 91日韩中文字幕| 中文字幕在线中文字幕二区| 99综合精品久久| 国产日韩中文字幕在线| 国产999在线观看| 日韩在线视频一区二区三区| 综合激情一区| 国产欧美高清在线| 亚洲第一视频在线观看| 久久欧美中文字幕| 欧美变态tickling挠脚心| 二区三区中文字幕| 午夜影院在线观看欧美| wwwav在线播放| 中文字幕亚洲字幕| 国产小视频免费在线网址| 精品国产免费观看一区| 亚洲欧洲日产国码av系列天堂| 国产123在线| 精品人妻一区二区三区视频| 中文字幕日韩第一页| 91精品国产91久久久久久青草| 精品人妻一区二区三区视频| 日韩国产专区| 色综合天天综合网国产成人综合天| 精品国产欧美日韩不卡在线观看| 亚洲国产欧美久久| 91九色在线看| 91精品国产自产91精品| 一二三区精品福利视频| 中文在线中文字幕| 欧美日韩在线观看一区| 一区二区三区在线播放视频| 亚洲视频 中文字幕| 国产午夜精品一区二区三区视频| 中文字幕乱码在线| 国产黄在线播放| 久久视频一区| 国产成人一区二区精品非洲| 中文字幕欧美人妻精品一区蜜臀| 日韩欧美一二三| 在线观看区一区二| 欧美日韩夫妻久久| 中文字幕日韩在线观看| 亚洲免费精品| 国产福利在线播放| 顶级网黄在线播放| 国产欧美久久久精品免费| 影音先锋中文字幕在线观看| 欧美另类专区| 色综合久久88色综合天天免费| 一区二区三区精品99久久| www.尤物.com| 青青国产91久久久久久| 欧美日韩国产免费观看视频| a√免费观看在线网址www| 亚洲成av人综合在线观看| 日本国产一区| 精品无人国产偷自产在线| 国产在线拍偷自揄拍精品| 在线免费播放av| 日韩在线小视频| 欧美婷婷精品激情| 91精品在线观看入口| 国产亚洲人成a一在线v站| 久久韩国免费视频| 日韩中文在线字幕| 日韩精品在线免费观看视频| 国产欧美日韩最新| 中文字幕日韩亚洲| 日本国产在线视频| 国产欧美日韩精品高清二区综合区| 国产在线中文字幕| 国产偷国产偷亚洲清高网站| 国产色综合网| 欧美日韩亚洲视频| 中文字幕国产在线| 首页国产欧美久久| 欧美日韩在线观看成人| 快she精品国产999| 欧美亚洲综合视频| 国产成免费视频| 国产自产视频| 999精品在线| 99久久精品国产成人一区二区| 亚洲羞羞网站| 欧美国产日韩综合| 国产在线欧美日韩| 中文字幕欧美亚洲| 日韩专区视频网站| 日韩在线 中文字幕| 亚洲一区二区三区精品中文字幕| 日韩欧美中文视频| 91xxx在线观看| 日本精品免费观看高清观看| 日韩欧美在线不卡| 中文字幕 欧美 日韩| 91精品国产高清久久久久久| 欧美在线视频二区| 久久91精品国产91久久小草| 欧美日韩亚洲国内综合网| 日韩国产成人精品| 日韩在线高清视频| 亚洲 欧美 日韩系列| 国产小视频免费在线观看| 91精品国产91久久久久久不卡| 91日韩中文字幕| 国产在线二区| 欧美日韩亚洲一区| 精品一区二区三区中文字幕| 久久精品在线免费观看| 日韩精品高清不卡| 久久99蜜桃精品久久久久小说| 精品福利一区二区三区| 国产综合精品在线| 高清日韩中文字幕| 国产欧美日韩中文字幕| 91精品国产自产| 日韩视频中文字幕| 亚洲福利精品在线| 中文字幕精品www乱入免费视频| 亚洲一区精品在线| 日韩精品福利一区二区三区| 视频一区二区国产| 欧美日韩国产在线播放| 国产婷婷精品| 精品中文字幕视频| 国产欧美日韩综合| 日韩在线二区| 欧美,日韩,国产在线| 亚洲免费在线视频一区 二区| 国产一区在线观看视频| 最近高清中文在线字幕在线观看| 在线精品视频免费播放| 国产网站欧美日韩免费精品在线观看| 国产亚洲人成a一在线v站| 国产一区激情在线| 在线免费视频一区二区| 欧美日韩国产观看视频| 国产网站欧美日韩免费精品在线观看| 国产三级视频在线播放线观看| 日韩亚洲欧美中文字幕| 欧美三级在线视频| 国产在线看一区| 国产一级粉嫩xxxx| 欧美三级日韩三级国产三级| 国产日韩精品在线| 成人无遮挡免费网站视频在线观看| 在线视频国内一区二区| 亚洲图片小说综合| 日韩视频精品在线观看| 一区二区三区在线|网站| 亚洲校园欧美国产另类| 色综合天天综合网天天狠天天| 日韩精品久久久| 日韩欧美高清在线视频| 国产黄色在线免费观看| 国产视频2区| 亚洲欧美视频一区二区三区| 欧美中文字幕在线| 中文字幕日韩欧美| 欧美日韩精品不卡| 日韩欧美高清在线视频| 日韩综合精品| 成人a在线视频免费观看| 91精品国产综合久久久蜜臀粉嫩| 欧美日韩精品欧美日韩精品一| 日韩精品免费观看视频| 免费一级欧美在线观看视频| 91精品婷婷国产综合久久竹菊| 成人福利一区| 日本精品专区| 国产日产一区二区三区| 日本一级一片免费视频| 中文字幕视频在线免费欧美日韩综合在线看| 国产午夜在线观看| 国产午夜精品视频免费不卡69堂| 日韩亚洲欧美中文在线| 欧美日韩尤物久久| 欧美日韩精品三区| 亚洲第一页中文字幕| 在线国产99| 精品亚洲成a人片在线观看| 亚洲第一页中文字幕| 视频一区二区精品的福利| www在线视频| 91精品久久久久久久久久| 久久精品免费在线观看| 色综合天天综合网天天狠天天| 精品久久九九| 亚洲va久久久噜噜噜久久| 国产香蕉精品视频| 中文字幕欧美日韩在线不卡| 日韩中文字幕视频网| 深夜日韩欧美| 日韩视频一区| 91精品国产免费久久综合| 日本一级一片免费视频| 视频一区日韩| 久久精品免费在线观看| 天堂在线一区二区三区| 91蜜桃婷婷狠狠久久综合9色| 99pao成人国产永久免费视频| 国产不卡精品在线| 国产欧美一级| 91精品国产91久久久久久久久| 欧美国产综合在线V| 91精品在线观| av一区二区高清| 国产欧美日韩中文字幕| 91久久精品国产91久久| 91精品国产综合久久久久久| 亚洲素人一区二区| 国产黄在线看| 在线视频一区二区三区在线播放| 不卡一二三区| 国产福利不卡| 亚洲福利一区| 中文在线不卡| 中文字幕在线视频久| 国产乱国产乱300精品| 老司机久久99久久精品播放免费| 国内不卡的二区三区中文字幕| 婷婷久久综合九色国产成人| 日韩欧美亚洲国产| 欧美 日韩 国产在线观看| 亚洲国产欧美日韩在线| 一区在线播放视频| 成人精品国产福利| 中文在线一区| 深夜福利亚洲| 国产高清视频一区二区| 99亚洲视频| 日韩亚洲一区中文字幕| 久久精品蜜桃| 高清国产一区| 91精品蜜臀在线一区尤物| 91精品国产91久久久久久不卡| 国产婷婷一区二区| 亚洲一区视频在线观看视频| 91九色在线播放| 国产成人精品免费在线| 中文字幕亚洲字幕| 日本啊v在线| 精品一性一色一乱农村| 中文精品在线| 日韩精品手机在线| 国产黄色网页| 日韩三级在线播放| 亚洲黄色在线观看| 中文字幕在线日韩| 欧美日韩成人一区二区| 精品久久久久久无| 亚洲国产一区自拍| 国产在线不卡av| 国产在线拍偷自揄拍精品| 热久久精品国产| 日韩欧美久久久| 99在线精品视频免费观看20| 欧美日韩免费不卡视频一区二区三区| 欧美日韩国产高清视频| av中文在线播放| 日韩一级在线免费观看| 一区二区三区久久| 国产三级视频在线| 国产高清在线观看| 欧美日韩中文字幕视频| 91久久精品国产91性色69| 日韩欧美在线网址| 国产一卡2卡3卡免费网站| 中文字幕 亚洲一区| 国产xxx在线| 精品国产免费观看一区| 中文字幕 日韩 欧美| 一区二区在线观看不卡| 91精品国产综合久久久久| 国产亚洲二区| 欧美 日韩 国产在线观看| 亚洲福利精品视频| 日韩中文字幕在线一区| 欧美三级中文字幕| 日韩国产成人| 亚洲a一级视频| 成年人看的羞羞网站| www日韩欧美| 国产不卡的av| 精品国产乱码一区二区| 亚洲国产91精品在线观看| 国产高清大尺度一区二区不卡| 亚洲免费精品视频| 中文字幕在线日韩| 免费精品国产自产拍在| 日韩欧美在线字幕| 91精品网站| 欧美日韩在线国产| 欧美日韩综合高清一区二区| 日本精品国语自产拍在线观看| 国产久卡久卡久卡久卡视频精品| 国产日产一区二区| 国产视频97| 午夜伦欧美伦电影理论片| 亚洲综合三区| 免费一级欧美在线观看视频| 最新中文字幕在线播放| 欧美日韩综合视频网址| 亚洲一区在线视频观看| 极品久久久久久| 国产日韩中文字幕| 欧美日韩精品久久久| 中文字幕在线亚洲| 国产色在线 com| 日本黄色一区二区三区| 不卡在线一区二区| 欧美亚洲国产激情| 日韩在线观看一区| 亚洲免费精品视频| 亚洲女人天堂a在线播放| 欧洲精品在线一区| 欧美日韩一级黄| 欧美日韩在线视频首页| 精品国产欧美| 亚洲免费观看视频| 精品在线91| 精品无人国产偷自产在线| 国产免费电影网站入口| 精品视频1区2区3区| 成年人黄国产| a在线观看免费视频| 亚洲成人7777| 91亚洲欧美| 国产h片在线观看| 国产中文在线视频| 日韩视频在线一区二区三区| 久久久精品国产免费观看同学| 国产在线观看色| 国自产拍在线网站网址视频| 91精品国产91久久久久久青草| 欧美专区中文字幕| 日韩精品高清不卡| 国产一级免费| 国产日韩av一区| 欧美日韩综合在线观看| www中文字幕| 日韩欧美三级在线| 国自产拍在线网站网址视频| 成年人看的羞羞网站| 91精品国产91久久久久| 一区二区三区在线播放视频| 日韩视频一区在线观看| 亚洲国产91精品在线观看| 日本中文字幕在线观看| 免费高清视频日韩| 国产欧美久久久久久久久| 狠狠色噜噜狠狠狠狠97| 天天综合天天综合| 欧美日韩中文字幕精品| 久久99久久久久| 日韩精品一区二区三区视频播放| 国产95在线|亚洲| 亚洲高清不卡一区| 中文字幕在线日韩| 一区二区国产在线| 日韩美女视频一区二区在线观看| 欧美日韩国产首页| 国产欧美日韩中文| 五月综合激情日本mⅴ| 91精品国产高清| 日韩免费视频一区二区| 91精品网站| 亚洲高清不卡一区| 日韩精品视频在线观看免费| 五月综合激情日本mⅴ| 国产成人精品日本亚洲专区61| 欧美日韩三级在线观看| 欧美日韩中文另类| 97天天综合网| 欧美一级在线观看|