1. 程式人生 > 其它 >CMU15445 Lecture 12 & 13 Query Execution

CMU15445 Lecture 12 & 13 Query Execution

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 = '阿黃';