<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] >[success] # 幾種值傳遞操作 1. **引入的賦值**:指向同一個對象,相互之間會影響; 2. **對象的淺拷貝**:只是淺層的拷貝,內部引入對象時,依然會相互影響; 3. **對象的深拷貝**:兩個對象不再有任何關系,不會相互影響 >[success] # 引用賦值 ~~~ const obj = { name: "123", age: 18, height: 1.88, friend: { name: "456" } } // 1.引用賦值 const info1 = obj ~~~ >[success] # 深淺拷貝 ~~~ 1.由于引用類型在賦值時只傳遞指針,這種拷貝方式稱為'淺拷貝'。 2.而創建一個新的與之相同的引用類型數據的過程稱之為'深拷貝'。 ~~~ >[info] ## 淺copy -- 的方法 ![](https://img.kancloud.cn/e7/4d/e74d50f3fabb7bf847702724ce6ca110_874x533.png) >[danger] ##### object.assign ~~~ 1.object.assign 的語法為:Object.assign(target, ...sources) 2.它不會copy 原型鏈上共享的屬性,不會copy 不可枚舉屬性,可以copy 'symbol' 類型 ~~~ ~~~ const obj = {a:{b:1},c:1,d:Symbol(10)} Object.defineProperty(obj,'e',{ value:"不可枚舉", enumerable:false }) const copyObj = {} // 返回值是目標對象 即Object.assign 整體的返回值也是copyObj Object.assign(copyObj,obj) console.log(copyObj) // { a: { b: 1 }, c: 1, d: Symbol(10) } obj.c = 100 obj.a.b = 200 console.log(copyObj); // { a: { b: 200 }, c: 1, d: Symbol(10) } ~~~ * 關于原型鏈上共享的屬性 ~~~ 1.原型鏈上共享的屬性 ~~~ ~~~ const obj = Object.create({foo: 1}, { // foo 是個繼承屬性。 bar: { value: 2 // bar 是個不可枚舉屬性。 }, baz: { value: 3, enumerable: true // baz 是個自身可枚舉屬性。 } }); const copy = Object.assign({}, obj); console.log(copy); // { baz: 3 } ~~~ * 如圖 ![](https://img.kancloud.cn/2d/bf/2dbf883711c98e78a5337174de05acbd_258x125.png) >[danger] ##### 擴展運算符 ~~~ 1.擴展運算符的語法為:let cloneObj = { ...obj } 2.它不會copy 原型鏈上共享的屬性,不會copy 不可枚舉屬性,可以copy 'symbol' 類型 ~~~ ~~~ const obj = {a:{b:1},c:1,d:Symbol(10)} Object.defineProperty(obj,'e',{ value:"不可枚舉", enumerable:false }) const copyObj = {...obj} console.log(copyObj) // { a: { b: 1 }, c: 1, d: Symbol(10) } obj.c = 100 obj.a.b = 200 console.log(copyObj); // { a: { b: 200 }, c: 1, d: Symbol(10) } ~~~ >[danger] ##### concat 拷貝數組 ~~~ let arr = [1, 2, 3]; let newArr = arr.concat(); newArr[1] = 100; console.log(arr); // [ 1, 2, 3 ] console.log(newArr); // [ 1, 100, 3 ] ~~~ >[danger] #### slice 拷貝數組 ~~~ let arr = [1, 2, {val: 4}]; let newArr = arr.slice(); newArr[2].val = 1000; console.log(arr); //[ 1, 2, { val: 1000 } ] ~~~ >[danger] ##### 實現一個自己的淺拷貝 ~~~ 1.實現的思路只要將數組或者是對象類型的數據最外層進行重新內存指向 ~~~ ~~~ const shallowClone = (target)=>{ // 淺拷貝將對象或者數組最外層copy一份 if(typeof target === "object" && target !==null){ const cloneTarget = Array.isArray(target)?[]:{} for(let key in target){ cloneTarget[key] = target[key] } return cloneTarget }else{ // 基本類型直接返回 return target } } ~~~ >[info] ## 深copy >[danger] ##### 30s js 的案例 ~~~ const deepClone = obj => { if (obj === null) return null; // 先淺copy 一層 let clone = Object.assign({}, obj); Object.keys(clone).forEach( key => (clone[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]) ); if (Array.isArray(obj)) { clone.length = obj.length; return Array.from(clone); } return clone; }; ~~~ >[danger] ##### JSON.stringfy() ~~~ 1.使用JSON.stringfy() 和 JSON.parse() 的方法將JSON 字符串生成一個新的對象,日常的簡單開發已經 夠用了 2.對應弊端 2.1.拷貝的對象的值中如果有函數、undefined、symbol 這幾種類型,經過 JSON.stringify 序列化之后 的字符串中這個鍵值對會消失 2.2.拷貝 Date 引用類型會變成字符串; 2.3.無法拷貝不可枚舉的屬性; 2.4.無法拷貝對象的原型鏈; 2.5.拷貝 RegExp 引用類型會變成空對象; 2.6.對象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的結果會變成 null; 2.7.無法拷貝對象的循環應用,即對象成環 (obj[key] = obj)。 ~~~ >[danger] ##### 第一版 ~~~ 1.深copy 時候,需要遍歷object 的key,遍歷一般采用'Object.keys 獲取鍵名或 for...in 方式遍歷',但是 這種處理方式不能針對'Symbol'類型做'key',想解決這個問題可以使用 'getOwnPropertyNames' 和 'getOwnPropertySymbols' 函數將鍵名組合成數組 2.getOwnPropertyNames 不單單可以獲取可枚舉屬性包括不可枚舉屬性,'Object.keys' 僅僅是對象自己的屬性, 非原型鏈上的,'for..in'循環遍歷整個原型鏈 二者都不能對不可枚舉 和symbols 數據返回,因此需要 'getOwnPropertyNames' 和'getOwnPropertySymbols' 函數將鍵名組合成數組 3.也可以使用Reflect.ownKeys(target)Reflect.ownKeys 方法返回一個由目標對象自身的屬性鍵組成的數組。 它的返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)) ~~~ [for...in 和 Object.keys ](http://www.hmoore.net/cyyspring/more/2079489) ~~~ function?clone(data)?{ ??let?result?=?{} // Reflect.ownKeys(data) ??const?keys?=?[...Object.getOwnPropertyNames(data),?...Object.getOwnPropertySymbols(data)] ??if(!keys.length)?return?data ??keys.forEach(key?=>?{ ????let?item?=?data[key] // null 的type類型也是object ????if?(typeof?item?===?'object'?&&?item)?{ ??????result[key]?=?clone(item) ????}?else?{ ??????result[key]?=?item ????} ??}) ??return?result } ~~~ * 吸取30s 數組也支持改進 ~~~ function clone (data) { if (typeof data === null || typeof data !== 'object') return data const result = {} // 獲取所有key const keys = Reflect.ownKeys(data) keys.forEach(key => { result[key] = typeof data[key] === 'object' ? clone(data[key]) : data[key] }) // length 因為使用了獲取不可枚舉的屬性相當于一獲取了 所以不用length 重新賦值 return Array.isArray(data) ? Array.from(result) : result } ~~~ >[danger] ##### 解決循環引用問題 ~~~ 1.添加一個 WeakMap 來記錄已經拷貝過的對象,如果當前對象已經被拷貝過,那么直接從 WeakMap 中取出, 否則重新創建一個對象并加入 WeakMap 中 var a = {} var b = {} a.b = b b.a = a ~~~ ~~~ function?clone(obj)?{ ??let?map?=?new?WeakMap() ??function?deep(data)?{ ????let?result?=?{} ????const?keys?=?[...Object.getOwnPropertyNames(data),?...Object.getOwnPropertySymbols(data)] ????if(!keys.length)?return?data ????const?exist?=?map.get(data) ????if?(exist)?return?exist ????map.set(data,?result) ????keys.forEach(key?=>?{ ??????let?item?=?data[key] ??????if?(typeof?item?===?'object'?&&?item)?{ ????????result[key]?=?deep(item) ??????}?else?{ ????????result[key]?=?item ??????} ????}) ????return?result ??} ??return?deep(obj) } ~~~ >[danger] ##### 在升級思考 ~~~ 1.當參數為 Date、RegExp 類型,則直接生成一個新的實例返回 2.考慮原型鏈上需要被原型鏈上的方法和屬性 ~~~ ~~~ const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null) const deepClone = function (obj, hash = new WeakMap()) { if (obj.constructor === Date) return new Date(obj) // 日期對象直接返回一個新的日期對象 可以使用instanceof 作為判斷 if (obj.constructor === RegExp) return new RegExp(obj) //正則對象直接返回一個新的正則對象 //如果循環引用了就用 weakMap 來解決 if (hash.has(obj)) return hash.get(obj) let allDesc = Object.getOwnPropertyDescriptors(obj) //遍歷傳入參數所有鍵的特性 這一步 如果是數組生成的就變成了數組 let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc) //繼承原型鏈 hash.set(obj, cloneObj) for (let key of Reflect.ownKeys(obj)) { cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key], hash) : obj[key] } return cloneObj } ~~~ >[info] ## jq 深淺copy ~~~ // $.extend(obj1,obj2,obj3) // 淺 // $.extend(true,obj1,obj2,obj3) // 深 jQuery.extend = jQuery.fn.extend = function () { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // 保證target是一個對象「第一個如果是布爾類型,是控制深淺合并的,讓其賦值給deep,并且讓target等于第二個實參{對象}」 if (typeof target === "boolean") { deep = target; target = arguments[i] || {}; i++; } if (typeof target !== "object" && !isFunction(target)) target = {}; // 只傳遞了一個對象,這種情況下,是為了給$/$.fn擴充方法的「也可以理解為,把傳遞對象中的每一項和$/$.fn進行合并」 if (i === length) { target = this; i--; } // target是多個對象合并中,被覆蓋的那個對象,我們拿其他傳遞的對象,依次覆蓋他即可 for (; i < length; i++) { // options就是剩余傳遞的某個對象 if ((options = arguments[i]) != null) { // 迭代options中的每一項,用其替換target中對應的項(如果target中沒有這一向,就是直接新加一個) for (name in options) { copy = options[name]; // 循環引用 if (name === "__proto__" || target === copy) { continue; } // 實現深度合并 if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { // src是要被替換的項 copy拿它替換src src = target[name]; if (copyIsArray && !Array.isArray(src)) { clone = []; } else if (!copyIsArray && !jQuery.isPlainObject(src)) { clone = {}; } else { clone = src; } copyIsArray = false; target[name] = jQuery.extend(deep, clone, copy); } else if (copy !== undefined) { // 淺合并 target[name] = copy; } } } } return target; }; ~~~ * 作為類工具類仿照 ~~~ class Tools { /** * 描述jq 的深淺copy * @date 2022-01-15 * @param {target} 合并的目標對象例如 extends(a,b) 則b和并到a 上,a為目標對象 * @param {options} 合并的配置對象例如 extends(a,b) 則b和并到a 上,b為被copy配置對象 * @param {deep} 深淺copy 默認淺copy 用法extends(true,a,b) b合并到a進行深copy * @param {name} 對象的key * @returns {any} */ extends() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false // 判斷是否為深度拷貝參數,如果是的話賦值給deep,并且設置拷貝目標為arguments[1] // 且修改類數組的長度i為2 // 舉例子 extends(false,a,b) 此時明確了是采用淺copy,因此實際合并對象就是從第二個參數開始 // 因此需要依次前移目標參數 if (typeof target === 'boolean') { deep = target target = arguments[1] || {} i = 2 } // 判斷傳入合并對象參數必須為對象,如果不是對象重置為對象 if (typeof target !== 'object') target = {} // 判斷參數長度是否等于i 來決定最后和調用本身進行合并 // 遞歸到最后來和自己本身合并 if (length === i) { target = this --i } // 開始前一個賦值給后一個對象 舉個例子 // extends(false,a,b) 即 b 合并給目標a for (; i < length; i++) { if ((options = arguments[i]) !== null) { // 對被拷貝的對象屬性進行循環 for...in 不能copy 不可枚舉的屬性 for (name in options) { src = target[name] copy = options[name] } // 防止循環引用 if (target === copy) continue // 判斷是否是深度拷貝,并且進行相應的操作 if ( (deep && copy && typeof copy === 'object') || (copyIsArray = Array.isArray(copy)) ) { // 如果目標對象為 {ls:1} 被克隆對象為{ls:[1,2,3]} // 則此時要把目標對象 合并 轉換為數組即 {ls:1} => {ls:[]} // 對象和數組同理 if (copyIsArray) { copyIsArray = false clone = src && Array.isArray(src) ? src : [] } else { clone = src && typeof src === 'object' ? src : {} } // 使用遞歸進行深度拷貝,且不修改原對象 target[name] = this.extend(deep, clone, copy) // 如果拷貝的對象為undefined則不進行拷貝 } else if (copy !== undefined) { target[name] = copy } } } } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看