我希望能够复制一个保留getter和setter功能的对象。
注意:这个问题是关于angularjs的,但它也可能适用于许多其他框架。
代码见:https://jsfiddle.net/vwb04d4f/2/
function out(str) {
document.getElementById('body').innerHTML += str + "<br>";
}
var SomeObj = function () {
var obj = {
_val: 0,
set val(value) {
out("Set: " + value);
this._val = value;
},
get val() {
return this._val;
}
}
return obj;
};
var sObj = new SomeObj();
sObj.val = 100;
var sCopy = angular.copy(sObj);
sCopy.val = 200;
out("Value:" + sCopy.val);
var sExt = angular.extend(sObj);
sExt.val = 300;
out("Value: " + sObj.val);
输出:
Set: 100
Value:200
Set: 300
Value: 300
为什么“angular.copy”之后不再触发“set val”?如您所见,该值已正确存储。
“angular.extend”保留引用,因此更新sExt将更新sObj,这是我不想要的。
我在将范围对象传递给控制器(模态)之前复制它:
$modal.open({
animation: true,
templateUrl: '/html/settings.html',
controller: 'ModalInstanceCtrl',
backdrop: false,
resolve: {
config: function() {
var cfgcpy = {};
angular.copy($scope.config, cfgcpy);
return cfgcpy;
}
}
}).result.then(function(res){
ok_func(res);
close_func();
}, function() {
close_func();
});
angular.module('app').controller('ModalInstanceCtrl', function ($scope, $modalInstance, config) {
$scope.config = config;
...
});
关于如何复制sObj而不丢失“set”和“get”并且不保留引用的任何想法?
**更新:
正如RichS提供的链接所指出的那样,似乎原因是getter和setter属性不可枚举,因此它们不会被复制。这个问题密切相关(如果我们找到问题的根源,则重复):Copy object with results of getters
我更新了代码:https://jsfiddle.net/vwb04d4f/3/
我手动添加了“enumerable”属性:
var SomeObj = function () {
var obj = {
_val: 0
}
Object.defineProperty(obj, "val", {
enumerable: true,
set : function(value) {
out("Set: " + value);
this._val = value;
},
get: function(){
return this._val;
}
});
return obj;
};
然而,无论是扩展(从空对象)还是复制都不能实际完成工作。也许我错过了什么?
**更新2 **
因为这个问题不仅与angularjs有关。
答案 0 :(得分:3)
我在这个问题中找到了一个解决方案:What is the most efficient way to deep clone an object in JavaScript?
function cloneObject(source) {
var key,value;
var clone = Object.create(source);
for (key in source) {
if (source.hasOwnProperty(key) === true) {
value = source[key];
if (value!==null && typeof value==="object") {
clone[key] = cloneObject(value);
} else {
clone[key] = value;
}
}
}
return clone;
}
请在此处查看更新后的代码:https://jsfiddle.net/vwb04d4f/6/
如您所见,“枚举”不是必需的。到目前为止,这段代码似乎解决了我的问题。谢谢Steven Vachon。
在这个问题上有很多解决方案,我测试了大部分解决方案,但并非全部。
答案 1 :(得分:0)