背景(爲什麼Object.update()
或jQuery.extend()
是不是一個解決方案,以及爲什麼這不是其他的how-to-複製一個JavaScript的對象問題,一式兩份): 這個版本的拷貝,使用一個for循環如何在保留獲取者/設置者的情況下淺拷貝Javascript對象?
function copy_obj(obj) {
var copy = {};
for (var attr in obj) if (obj.hasOwnProperty(attr)) {
copy[attr] = obj[attr];
}
return copy;
}
只複製屬性的值(一樣Object.update()
)和失敗的物體上,如:
var myobj = {
_fname: 'fname',
_lname: 'lname',
get fullname() { return this._fname + ' ' + this._lname; },
set fullname(v) { this._fname = v; }
};
即
myobj.fullname === 'fname lname' // true
myobj.fullname = 'Anton'
myobj.fullname === 'Anton lname' // true
而
var mycopy = copy_obj(myobj);
mycopy.fullname === 'fname lname' // true
mycopy.fullname = 'Anton'
mycopy.fullname === 'Anton' // oops!
問:我已經想通了,我需要使用getOwnPropertyNames /描述獲取/設置的描述,但我還沒有找到任何簡單的方法來確定,如果事情僅僅是一個普通的可以直接複製值 - 什麼進入if語句:
function copy_obj2(obj) {
var mycopy = {};
Object.getOwnPropertyNames(obj).forEach(function (prop) {
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
if (/* descriptor is a plain value */) {
mycopy[prop] = obj[prop];
} else {
Object.defineProperty(mycopy, prop, descriptor);
}
});
return mycopy;
}
(我只是在複製類似對象的值,而不關心陣列或其他基本類型)。
你爲什麼會在乎它是什麼類型的描述符? 'Object.defineProperty'也可以用來創建數據屬性。 – Bergi
提示:「簡單」描述符具有'可寫'和'值'字段,不含'get'或'set'字段。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors#Description – Bergi
不是一個數據描述符/屬性比普通的價值更多的開銷? – thebjorn