使用js實(shí)現(xiàn)復(fù)制功能
本文實(shí)例為大家分享了使用js實(shí)現(xiàn)復(fù)制功能的具體代碼,供大家參考,具體內(nèi)容如下
復(fù)制
1.遍歷復(fù)制(for in)
特征:不修改引用關(guān)系(原來(lái)的屬性還在),僅能復(fù)制字符屬性,Symbol不能復(fù)制,不可枚舉屬性不能復(fù)制,原型鏈不能復(fù)制。淺復(fù)制
2.JOSN.parse(JSON.stringify(obj)) 轉(zhuǎn)換復(fù)制
特征:修改引用關(guān)系(相當(dāng)于創(chuàng)建一個(gè)新的對(duì)象,不再擁有原來(lái)的屬性),僅能復(fù)制字符屬性,Symbol不能復(fù)制,不可枚舉屬性不能復(fù)制,原型鏈不能復(fù)制,函數(shù)和其他類型不能復(fù)制。深復(fù)制
3.{…obj}解構(gòu)賦值復(fù)制
特征:修改引用關(guān)系,Symbol和函數(shù)都能復(fù)制,不可枚舉屬性和原型鏈都不能復(fù)制。淺復(fù)制
4.Object.assign()對(duì)象復(fù)制
特征:不修改引用關(guān)系,可以復(fù)制屬性、方法、Symbol類型,不可枚舉屬性和原型鏈都不能復(fù)制。淺復(fù)制
深復(fù)制**
1.使用defineProperty***
function cloneObject(source,target){ ? ? if(source === null||source === undefined) return source; ? ? if(source===document) return; ? ? //判斷target是不是繼承對(duì)象的實(shí)例,是不是引用類型(null,undefined,Boolean,string,number都不是引用類型) ? ? if(!Object.prototype.isPrototypeOf(target)){ ? ? ? ? //判斷源對(duì)象是不是dom元素 ? ? ? ? if(HTMLElement.prototype.isPrototypeOf(source)){ ? ? ? ? ? ? //創(chuàng)建dom元素 ? ? ? ? ? ? ?target = document.createElement(source.nodeName); ? ? ? ? }else if(source.constructor === RegExp){ ? ? ? ? ? ? // 任何正則表達(dá)式都有source和flags,source是正則內(nèi)容,flags是正則修飾符 ? ? ? ? ? ? // 因?yàn)檫@兩個(gè)屬性都是只讀屬性,不能寫(xiě)入,必須通過(guò)構(gòu)造函數(shù)創(chuàng)建時(shí)帶入 ? ? ? ? ? ? target = new RegExp(source.source,source.flags); ? ? ? ? }else if(source.constructor === Date){ ? ? ? ? ? ? // 日期對(duì)象在創(chuàng)建的對(duì)象中將原有的日期對(duì)象放入,可以讓當(dāng)前日期對(duì)象變?yōu)樵腥掌趯?duì)象的值,但是沒(méi)有引用關(guān)系 ? ? ? ? ? ? targer = new Date(source); ? ? ? ? }else if(source.constructor === Function){ ? ? ? ? ? ? // 復(fù)制函數(shù),通過(guò)正則表達(dá)式將函數(shù)中的參數(shù)以及函數(shù)體內(nèi)容提取到數(shù)組中,然后通過(guò)new Function()創(chuàng)建 ? ? ? ? ? ? var arr = source.toString().replace(/\n|\r/g,"").trim().match(/\((.*?)\)\s*\{(.*)\}/).slice(1); ? ? ? ? ? ? target = new Function(arr[0].trim(),arr[1]); ? ? ? ? }else if(source.constructor === Set){ ? ? ? ? ? ? // set類型,在處理時(shí),new Set時(shí)可以帶入數(shù)組,因此我們將原有set的列表強(qiáng)轉(zhuǎn)為數(shù)組,并且將這個(gè)強(qiáng)轉(zhuǎn)后的數(shù)組復(fù)制給新數(shù)組 ? ? ? ? ? ? target = new Set(cloneObject(Array.from(source.values()))); ? ? ? ? }else if(source.constructor === Map){ ? ? ? ? ? ? target = new Map(); ? ? ? ? ? ? // 如果是map類型,遍歷map中每個(gè)元素 ? ? ? ? ? ? for(var [key,value] of source.entries()){ ? ? ? ? ? ? ? ? // 如果key是引用類型, ? ? ? ? ? ? ? ? if(Object.prototype.isPrototypeOf(key)){ ? ? ? ? ? ? ? ? ? ? ?// 如果value引用類型,則將key和value分別做復(fù)制,并且將返回的結(jié)果放在map中 ? ? ? ? ? ? ? ? ? ? if(Object.prototype.isPrototypeOf(value)){ ? ? ? ? ? ? ? ? ? ? ? ? target.set(cloneObject(key),cloneObject(value)); ? ? ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? ?//如果value不是引用類型,只將key復(fù)制,并且放入map ? ? ? ? ? ? ? ? ? ? ? ? target.set(cloneObject(key),value); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? // 這是key不是引用類型時(shí) ? ? ? ? ? ? ? ? ? ? if(Object.prototype.isPrototyeOf(value)){ ? ? ? ? ? ? ? ? ? ? ? ? target.set(key,cloneObject(value)); ? ? ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? target.set(key,value); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? else{ ? ? ? ? //除了null和undefined,其他類型都有constructor。任何對(duì)象的constructor都是它的類型,利用其constructor創(chuàng)建對(duì)象 ? ? ? ? //通過(guò)對(duì)象類型的反射創(chuàng)建新的同類型對(duì)象 ? ? ? ? ? ? target = new source.constructor(); ? ? ? ? } ? ? ? ?? ? ? } ? ? //獲取對(duì)象的所有字符屬性名和Symbol屬性名的數(shù)組 ? ? var names = Object.getOwnPropertyName(source).concat(Object.getOwnPropertySymbols(source)); ? ? for(var i = 0;i < names.lenght; i++){ ? ? ? ? // 如果當(dāng)前復(fù)制的是函數(shù),并且這個(gè)函數(shù)的屬性是prototype,那么這個(gè)屬性不復(fù)制,否則會(huì)死循環(huán) ? ? ? ? if(source.constructor === Function&&names[i] === "prototype") ? ? ? ? ? ? continue; ? ? ? ? // 獲取當(dāng)前屬性名的描述對(duì)象 ? ? ? ? var desc = Object.getOwnPropertyDescriptor(source,names[i]); ? ? ? ? // ? 這個(gè)描述對(duì)象的值如果是引用類型 ? ? ? ? if(Object.prototype.isPrototypeOf(desc.value)){ ? ? ? ? ? ? ?// 根據(jù)需要將源對(duì)象的描述內(nèi)容設(shè)置給當(dāng)前目標(biāo)對(duì)象相同屬性名的描述內(nèi)容,及值付為剛才創(chuàng)建相同類型的對(duì)象 ? ? ? ? ? ? Object.defineProperty(target,names[i],{ ? ? ? ? ? ? ? ? enumerable:desc.enumerable, ? ? ? ? ? ? ? ? configurable:desc.configurable, ? ? ? ? ? ? ? ? writable:desc.writable, ? ? ? ? ? ? ? ? value:cloneObject(desc.value) ? ? ? ? ? ? }); ? ? ? ? }else{ ? ? ? ? ? ? ?//如果描述的對(duì)象的值不是引用類型,直接將描述對(duì)象設(shè)置給目標(biāo)對(duì)象的這個(gè)屬性 ? ? ? ? ? ? Object.defineProperty(target,names.desc); ? ? ? ? } ? ? } ? ? return target; } //原型.isPrototypeOf(對(duì)象)。對(duì)象里面是不是擁有xx的原型 //反射:通過(guò)對(duì)象
2.使用JSON對(duì)象實(shí)現(xiàn)深復(fù)制
使用**JSON.parse(str)**可以將字符串轉(zhuǎn)換成對(duì)象;
使用**JSON.stringify(obj)**將對(duì)象轉(zhuǎn)換成對(duì)象形式的字符串,其中無(wú)法轉(zhuǎn)換對(duì)象中的方法,可以考慮先將對(duì)象中的方法使用toString()轉(zhuǎn)為字符串,然后再轉(zhuǎn)換使用JSON.stringify(obj);
*使用**JSON.parse(str)**可以將字符串轉(zhuǎn)換成對(duì)象
var obj={ ? ? a:1, ? ? b:3,?? ?//ab復(fù)制不會(huì)隨其中一個(gè)的變化而變化 ? ? c:{?? ??? ?//c復(fù)制會(huì)隨其中一個(gè)的變化而變化,因?yàn)閏屬于對(duì)象的地址引用關(guān)系 ? ? ? ? d:10, ? ? ? ? e:20 ? ? } }; var o1 = JSON.parse(JSON.stringify(obj)); //將obj復(fù)制給o1
3.使用遞歸實(shí)現(xiàn)深復(fù)制
結(jié)構(gòu)僅限于對(duì)象。如果存在數(shù)組、正則、日期對(duì)象、dom對(duì)象則不能使用。
var obj = { a:1, b:2, c:{ ?? ??? ?a:1, ? b:2, ? c:{ ?? ??? ??? ?a:1, ? ? ? b:2, ? ? ? } } } //函數(shù)定義參數(shù)時(shí),注意必要參數(shù)寫(xiě)在前面,非必要參數(shù)寫(xiě)在后面 function cloneObj(source,target){ ?? ?if(target === undefined) target = {}; for(var prop in source){ ? //如果 ?? ??? ?if(typeof source[prop] === "object" && source[prop] != null){ ? ? ? target[prop] = {}; ? ? ? cloneObj(source[prop],target[prop]); ? }else{ ?? ??? ??? ?target[prop] = source[prop]; ? } } return target; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JavaScript實(shí)現(xiàn)一鍵復(fù)制文本功能的示例代碼
- Web js實(shí)現(xiàn)復(fù)制文本到粘貼板
- 使用?JS?復(fù)制頁(yè)面內(nèi)容的三種方案
- JavaScript實(shí)現(xiàn)一鍵復(fù)制內(nèi)容剪貼板
- js復(fù)制文本到粘貼板(Clipboard.writeText())
- JS實(shí)現(xiàn)一鍵復(fù)制
- Vue中使用highlight.js實(shí)現(xiàn)代碼高亮顯示以及點(diǎn)擊復(fù)制
- js實(shí)現(xiàn)復(fù)制粘貼的兩種方法
- JavaScript+Html5實(shí)現(xiàn)按鈕復(fù)制文字到剪切板功能(手機(jī)網(wǎng)頁(yè)兼容)
- JS實(shí)現(xiàn)復(fù)制內(nèi)容到剪貼板功能兼容所有瀏覽器(推薦)
- js實(shí)現(xiàn)點(diǎn)擊復(fù)制當(dāng)前文本到剪貼板功能(兼容所有瀏覽器)
- 簡(jiǎn)單實(shí)現(xiàn)兼容各大瀏覽器的js復(fù)制內(nèi)容到剪切板
- JavaScript 實(shí)現(xiàn)完美兼容多瀏覽器的復(fù)制功能代碼
- 兼容主流瀏覽器的JS復(fù)制內(nèi)容到剪貼板
- js實(shí)現(xiàn)的復(fù)制兼容chrome和IE
- 兼容所有瀏覽器的js復(fù)制插件Zero使用介紹
- 用js將內(nèi)容復(fù)制到剪貼板兼容瀏覽器
- js復(fù)制網(wǎng)頁(yè)內(nèi)容并兼容各主流瀏覽器的代碼
- JS復(fù)制內(nèi)容到剪切板的實(shí)例代碼(兼容IE與火狐)
- JS/FLASH實(shí)現(xiàn)復(fù)制代碼到剪貼板(兼容所有瀏覽器)
- 多瀏覽器兼容性比較好的復(fù)制到剪貼板的js代碼
- GWT中復(fù)制到剪貼板 js+flash實(shí)現(xiàn)復(fù)制 兼容性比較好
- 兼容IE與Firefox的js 復(fù)制代碼
- JavaScript 復(fù)制功能代碼 兼容多瀏覽器
- 至2023年最好用的兼容多瀏覽器的原生js復(fù)制函數(shù)copyText
相關(guān)文章
localResizeIMG先壓縮后使用ajax無(wú)刷新上傳(移動(dòng)端)
隨著技術(shù)的發(fā)展,移動(dòng)設(shè)備像素越來(lái)越高,但是這么大的圖片怎么上傳呢?下面小編就給大家一起學(xué)習(xí)移動(dòng)端圖片上傳的方法之localResizeIMG先壓縮后使用ajax無(wú)刷新上傳,需要的朋友可以參考下2015-08-08使用JS實(shí)現(xiàn)圖片輪播的實(shí)例(前后首尾相接)
下面小編就為大家?guī)?lái)一篇使用JS實(shí)現(xiàn)圖片輪播的實(shí)例(前后首尾相接)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09整理Javascript基礎(chǔ)語(yǔ)法學(xué)習(xí)筆記
整理Javascript基礎(chǔ)語(yǔ)法學(xué)習(xí)筆記,之前一系列的文章是跟我學(xué)習(xí)Javascript,本文就是進(jìn)一步學(xué)習(xí)javascript基礎(chǔ)語(yǔ)法,希望大家繼續(xù)關(guān)注2015-11-11javascript使用appendChild追加節(jié)點(diǎn)實(shí)例
這篇文章主要介紹了javascript使用appendChild追加節(jié)點(diǎn)的方法,實(shí)例分析了appendChild()函數(shù)增加結(jié)點(diǎn)的使用技巧,需要的朋友可以參考下2015-01-01Javascript 數(shù)組添加 shuffle 方法的實(shí)現(xiàn)代碼
PHP 里面有個(gè)非常方便的打亂數(shù)組的函數(shù) shuffle() ,這個(gè)功能在許多情況下都會(huì)用到,但 javascript 的數(shù)組卻沒(méi)有這個(gè)方法,沒(méi)有不要緊,可以擴(kuò)展一個(gè),自己動(dòng)手,豐衣足食嘛。2009-09-09javascript實(shí)現(xiàn)編寫(xiě)網(wǎng)頁(yè)版計(jì)算器
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)編寫(xiě)網(wǎng)頁(yè)版計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08JavaScript實(shí)現(xiàn)單擊網(wǎng)頁(yè)任意位置打開(kāi)新窗口與關(guān)閉窗口的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)單擊網(wǎng)頁(yè)任意位置打開(kāi)新窗口與關(guān)閉窗口的方法,涉及javascript窗口的相關(guān)操作函數(shù)與使用技巧,需要的朋友可以參考下2017-09-09PixiJS學(xué)習(xí)之如何實(shí)現(xiàn)文字的繪制
PixiJS是一個(gè)開(kāi)源的基于web的渲染系統(tǒng),為游戲、數(shù)據(jù)可視化和其他圖形密集型項(xiàng)目提供了極快的性能。這篇文章主要帶大家學(xué)習(xí)一下PixiJS是如何實(shí)現(xiàn)文字繪制的,希望對(duì)大家有所幫助2023-02-02關(guān)于數(shù)據(jù)與后端進(jìn)行交流匹配(點(diǎn)亮星星)
這篇文章主要介紹了關(guān)于數(shù)據(jù)與后端進(jìn)行交流匹配(點(diǎn)亮星星) 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08