2008年11月17日
[JavaScript] 複製物件
前幾天遇到了一個 JavaScript 的小問題,就是物件的複製。
這個問題主要是我先設定了一個全域變數,然後在函式裡去重新定義一個變數,並將全域變數的內容指定給新變數。
我以為這樣就是「複製了 JavaScript 的物件」,但事實上是錯的。
我特地上網找了一下,發現 JavaScript 本身並沒有提供比較方便的 clone 機制,這時我的腦筋就動到 jQuery 上了。
不過這裡我可不是說 jQuery 的 clone 方法,而是 extend 方法。
先來看看例子好了:
<html>
<head>
<script type="text/javascript" src="jquery/1.2.6.js"></script>
<script type="text/javascript">
function w(s) {
document.write(s + '<br />\n');
}
function d(o) {
var s = '';
for (var i in o) {
s += i + ': ' + o[i] + '<br />\n';
}
w(s);
}
</script>
</head>
<body>
<script type="text/javascript">
var o1 = {
a1: '123',
a2: '456'
};
var o2 = o1;
$.extend(o2, { a3: '789' });
var o3 = $.extend({}, o1);
$.extend(o3, { a4: '000' });
w('o1');
d(o1);
w('o2');
d(o2);
w('o3');
d(o3);
</script>
</body>
</html>
在上面的程式中,請將重點放在我強調的部份。
這裡我先定義一個自訂物件 o1 ,然後我將 o2 指定為 o1 ;在 JavaScript 的意義裡, o2 就會是 o1 的「別名」,兩個都指到同一個物件。
因此接下來我對 o2 進行任何操作,都會影響到 o1 ;也就是說如果我們要複製 o1 的話,就不能用等號 (=) 。
jQuery 的 extend 方法可以幫我們這個忙。
原因是 extend 會將第二個參數裡的物件成員,一項一項地複製到第一個參數上。因此我們可以用它來解決 JavaScript 複製物件的問題。
在 o1 複製到 o3 中,很重要的一個關鍵就是我們需要把 $.extend 的第一個參數設為空物件;這是因為 $.extend 會回傳第一個參數,我們就省掉先行定義 o3 為空物件的動作了。
接下來我們不論怎麼對 o3 進行處理,也不會影響到 o1 ;換句話說,我們已經成功達成 clone JavaScript Object 的目標啦。
