C++指標、陣列和指標算數
阿新 • • 發佈:2022-03-06
1、基本型別的拷貝
先開看一段非常經典的程式碼
var a = 1;
var b = a;
a = 200;
console.log(a);//200
console.log(b);//1
基本型別是按值傳遞
,引用型別按引用傳遞
,數值作為基本型別是儲存在棧記憶體中,可以直接拿來用的,賦值時什麼就是什麼,不會受到傳遞元素的改變帶來影響。
引用型別的拷貝
簡單說,引用型別是生成一個指標儲存在堆記憶體中,當給引用型別賦值時,我們的寫的是在棧記憶體中,也就是說我們拿到的其實是一個指標。這個指標是指向了棧記憶體中這個引用型別的程式碼。
提到拷貝涉及到的兩種拷貝型別:深拷貝和淺拷貝
淺拷貝
var a = { name:'mjj', age:20, hobby:'eat', friend:{ name:'alex', age:38 } } function shadowCopy(to,from){ for(var key in from){ to[key] = from[key] } return to; } var newObj = shadowCopy({},a); newObj.age = 18; newObj.friend.name = '阿黃'; /* { age: 20,//沒被改變 friend: { name: "阿黃",//同時被改變,說明是同一個引用 age: 38 }, hobby: "eat" name: "mjj } */
我們發現,首先,淺拷貝不是直接賦值,淺拷貝新建了一個物件,然後將源物件的屬性都一一複製過來,複製的是值,而不是引用。
我們知道,物件都是按地址引用進行訪問的,淺拷貝的複製只複製了第一層的屬性,並沒有遞迴將所有的值複製過來,所以,操作拷貝資料,對原資料產生了影響,故而為淺拷貝。
深拷貝
使用深拷貝可以使新建立的物件和原來的完全脫離關係
var a = { name:'mjj', age:20, hobby:'eat', friend:{ name:'alex', age: 38, hobby:'雞湯' } } function deepCopy(to,from){ for(var key in from){ //不遍歷原型鏈上的屬性 if(from.hasOwnProperty(key)){ //如果值是物件並且有值,則遞迴一下 if(from[key] && typeof from[key] === 'object'){ //區分是一般物件還是陣列物件 to[key] = from[key].constructor === Array ? []: {}; to[key] = deepCopy(to[key],from[key]); }else{ //如果不是,就直接賦值 to[key] = from[key]; } } } return to; } var newObj = deepCopy(a); newObj.age = 18; newObj.friend.name = '阿黃';