<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
深拷貝和淺拷貝是隻針對Object和Array這樣的參照資料型別的。
淺拷貝是建立一個新物件,該物件有著原始物件屬性值的一份精確拷貝。如果屬性是基本型別,拷貝的就是基本型別的值,如果屬性是參照型別,拷貝的就是記憶體地址 ,所以如果其中一個物件改變了這個地址,就會影響到另一個物件。
範例程式碼:
let people = { //定義一個People物件 name: "張三", age: 3, address: "中國" } console.log("原物件:", people); let newPeople = people; //進行淺拷貝 console.log("新物件:", newPeople); //原物件: { name: '張三', age: 3, address: '中國' } //新物件: { name: '張三', age: 3, address: '中國' } //為物件修改名字 newPeople.name = "橘貓吃不胖"; console.log("原物件:", people); console.log("新物件:", newPeople); //原物件: { name: '橘貓吃不胖', age: 3, address: '中國' } //新物件: { name: '橘貓吃不胖', age: 3, address: '中國' }
從上面的範例可以看出,當newPeople的name屬性修改後,原來的people也發生了變化,這是因為新建立的物件與舊物件具有相同的記憶體地址。
深拷貝是將一個物件從記憶體中完整的拷貝一份出來,從堆記憶體中開闢一個新的區域存放新物件,且修改新物件不會影響原物件。
範例程式碼:
let people = { //定義一個People物件 name: "張三", age: 3, address: "中國" } //對people進行深拷貝 let newPeople = JSON.parse(JSON.stringify(people)); console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '張三', age: 3, address: '中國' } //修改新物件中的adress屬性 newPeople.address = "俄羅斯"; console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '張三', age: 3, address: '俄羅斯' }
從上面的例子可以看出,深拷貝後,修改新物件,不會影響原物件。
Object.assign()
方法用於將所有可列舉屬性的值從一個或多個源物件分配到目標物件。它將返回目標物件。Object.assign() 進行的是淺拷貝,拷貝的是物件的屬性的參照,而不是物件本身。
語法:
Object.assign(target, ...sources) //target:目標物件;sources:源物件。
如果目標物件中的屬性具有相同的鍵,則屬性將被源物件中的屬性覆蓋。後面的源物件的屬性將類似地覆蓋前面的源物件的屬性。
範例:
const target = { a: 1, b: 2 }; const source = { b: 4, c: 5 }; //進行淺拷貝 const returnedTarget = Object.assign(target, source); console.log(target); console.log(returnedTarget); // { a: 1, b: 4, c: 5 } // { a: 1, b: 4, c: 5 } //修改其中的值 target.b = 10; console.log(target); console.log(returnedTarget); // { a: 1, b: 10, c: 5 } // { a: 1, b: 10, c: 5 }
當物件object只有一層的時候,是深拷貝,範例程式碼如下:
const obj = { name: "橘貓吃不胖" }; //進行淺拷貝 let newObj = Object.assign({}, obj); //修改新物件中的name屬性為張三 newObj.name = "張三"; console.log("原物件:", obj); console.log("新物件:", newObj); // 原物件: { name: '橘貓吃不胖' } // 新物件: { name: '張三' }
concat()方法用於合併兩個或多個陣列。此方法不會更改現有陣列,而是返回一個新陣列。
語法:
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]]) //valueN可選,陣列和/或值,將被合併到一個新的陣列中。 //如果省略了所有 valueN 引數,則 concat 會返回撥用此方法的現存陣列的一個淺拷貝。
範例程式碼:
let arr1 = [1, 2, { name: "橘貓吃不胖" }]; //進行淺拷貝 let arr2 = arr1.concat(); console.log("原陣列:", arr1); console.log("新陣列:", arr2); // 原陣列: [ 1, 2, { name: '橘貓吃不胖' } ] // 新陣列: [ 1, 2, { name: '橘貓吃不胖' } ] //修改原陣列 arr1[1] = "hhhhh"; console.log("原陣列:", arr1); console.log("新陣列:", arr2); // 原陣列: [ 1, 'hhhhh', { name: '橘貓吃不胖' } ] // 新陣列: [ 1, 2, { name: '橘貓吃不胖' } ]
slice() 方法返回一個新的陣列物件,這一物件是一個由 begin 和 end 決定的原陣列的淺拷貝(包括 begin,不包括end)。原始陣列不會被改變。
語法:
arr.slice([begin[, end]]) //begin:可選,提取起始處的索引(從 0 開始),從該索引開始提取原陣列元素。 //如果該引數為負數,則表示從原陣列中的倒數第幾個元素開始提取,slice(-2) 表示提取原陣列中的倒數第二個元素到最後一個元素(包含最後一個元素)。 //如果省略 begin,則 slice 從索引 0 開始。 //如果 begin 超出原陣列的索引範圍,則會返回空陣列。 //end:可選,提取終止處的索引(從 0 開始),在該索引處結束提取原陣列元素。slice 會提取原陣列中索引從 begin 到 end 的所有元素(包含 begin,但不包含 end)。 //slice(1,4) 會提取原陣列中從第二個元素開始一直到第四個元素的所有元素 (索引為 1, 2, 3的元素)。 //如果該引數為負數, 則它表示在原陣列中的倒數第幾個元素結束抽取。 slice(-2,-1) 表示抽取了原陣列中的倒數第二個元素到最後一個元素(不包含最後一個元素,也就是隻有倒數第二個元素)。 //如果 end 被省略,則 slice 會一直提取到原陣列末尾。 //如果 end 大於陣列的長度,slice 也會一直提取到原陣列末尾。
範例程式碼:
let arr1 = [1, 2, { name: "橘貓吃不胖" }]; //進行淺拷貝 let arr2 = arr1.slice(); console.log("原陣列:", arr1); console.log("新陣列:", arr2); // 原陣列: [ 1, 2, { name: '橘貓吃不胖' } ] // 新陣列: [ 1, 2, { name: '橘貓吃不胖' } ] //修改原陣列 arr1[1] = "hhhhh"; console.log("原陣列:", arr1); console.log("新陣列:", arr2); // 原陣列: [ 1, 'hhhhh', { name: '橘貓吃不胖' } ] // 新陣列: [ 1, 2, { name: '橘貓吃不胖' } ]
直接使用“=”賦值可以實現淺拷貝,範例程式碼如下:
let obj1 = { //定義一個物件obj1 name: "張三", age: 34 } let obj2 = obj1; //進行淺拷貝 console.log("obj1:", obj1); console.log("obj2:", obj2); // obj1: { name: '張三', age: 34 } // obj2: { name: '張三', age: 34 } //修改obj2中的name屬性 obj2.name = "橘貓吃不胖"; console.log("obj1:", obj1); console.log("obj2:", obj2); // obj1: { name: '橘貓吃不胖', age: 34 } // obj2: { name: '橘貓吃不胖', age: 34 }
JSON是一種語法,用來序列化物件、陣列、數值、字串、布林值和 null 。它基於JavaScript語法,但與之不同:JavaScript不是JSON,JSON也不是JavaScript。
JSON物件包含兩個方法:用於解析JSON的parse()方法,以及將物件/值轉換為JSON字串的stringify()方法,下面對這兩種方法進行一些介紹。
JSON.parse()
方法用來解析JSON字串,構造由字串描述的JavaScript值或物件。提供可選的 reviver 函數用以在返回之前對所得到的物件執行變換(操作)。
語法:
JSON.parse(text[, reviver]) //text:要被解析成 JavaScript 值的字串 //reviver,可選,轉換器, 如果傳入該引數(函數),可以用來修改解析生成的原始值,呼叫時機在 parse 函數返回之前。
範例:
JSON.parse('{}'); // {} JSON.parse('true'); // true JSON.parse('"foo"'); // "foo" JSON.parse('[1, 5, "false"]'); // [1, 5, "false"] JSON.parse('null'); // null
JSON.stringify()
方法將一個 JavaScript 物件或值轉換為 JSON 字串,如果指定了一個 replacer 函數,則可以選擇性地替換值,或者指定的 replacer 是陣列,則可選擇性地僅包含陣列指定的屬性。
語法:
JSON.stringify(value[, replacer [, space]]) //value:將要序列化成 一個 JSON 字串的值。 //replacer,可選,如果該引數是一個函數,則在序列化過程中,被序列化的值的每個屬性都會經過該函數的轉換和處理;如果該引數是一個陣列,則只有包含在這個陣列中的屬性名才會被序列化到最終的 JSON 字串中;如果該引數為 null 或者未提供,則物件所有的屬性都會被序列化。 //space,可選,指定縮排用的空白字串,用於美化輸出(pretty-print);如果引數是個數位,它代表有多少的空格;上限為10。該值若小於1,則意味著沒有空格;如果該引數為字串(當字串長度超過10個字母,取其前10個字母),該字串將被作為空格;如果該引數沒有提供(或者為 null),將沒有空格。
範例:
JSON.stringify({}); // '{}' JSON.stringify(true); // 'true' JSON.stringify("foo"); // '"foo"' JSON.stringify([1, "false", false]); // '[1,"false",false]' JSON.stringify({ x: 5 }); // '{"x":5}'
深拷貝範例程式碼:
let people = { //定義一個People物件 name: "張三", age: 3, address: "中國" } //對people進行深拷貝 let newPeople = JSON.parse(JSON.stringify(people)); console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '張三', age: 3, address: '中國' } //修改新物件中的adress屬性 newPeople.address = "俄羅斯"; console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '張三', age: 3, address: '俄羅斯' }
用JSON.stringify將物件轉成JSON字串,再用JSON.parse()把字串解析成物件,這樣新的物件產生了,實現深拷貝。這種方法雖然可以實現陣列或物件深拷貝,但不能處理常式。
let arr1 = [1, 2, { name: "橘貓吃不胖" }, function () { }]; //進行深拷貝 let arr2 = JSON.parse(JSON.stringify(arr1)); console.log("原陣列:", arr1); console.log("新陣列:", arr2); // 原陣列: [ 1, 2, { name: '橘貓吃不胖' }, [Function (anonymous)] ] // 新陣列: [ 1, 2, { name: '橘貓吃不胖' }, null ]
由上面例子可以看出,函數並沒有被拷貝在arr2中。這是因為 JSON.stringify() 方法是將一個JavaScript值(物件或者陣列)轉換為一個 JSON字串,不能接受函數。
Lodash是一個JavaScript庫,提供了多個實用程式功能,而Lodash庫中最常用的功能之一是cloneDeep()方法。此方法有助於深度克隆物件,還可以克隆JSON.stringify()方法的侷限性,即不可序列化的屬性。
範例程式碼:
const lodash = require("lodash"); let people = { name: "張三", age: 3, address: "中國" } //對people進行深拷貝 let newPeople = lodash.cloneDeep(people); console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '張三', age: 3, address: '中國' } //修改新物件中的adress屬性 newPeople.address = "俄羅斯"; newPeople.name = "橘貓吃不胖"; console.log("原物件:", people); console.log("新物件:", newPeople); // 原物件: { name: '張三', age: 3, address: '中國' } // 新物件: { name: '橘貓吃不胖', age: 3, address: '俄羅斯' }
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45