Javascript:对象设置器和获取器在克隆/复制/扩展后丢失
Posted
技术标签:
【中文标题】Javascript:对象设置器和获取器在克隆/复制/扩展后丢失【英文标题】:Javascript: object's setter and getter is lost after clonning / copying / extending 【发布时间】:2016-01-17 08:44:11 【问题描述】:我希望能够复制一个保持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;
...
);
关于如何在不丢失“set”和“get”且不保留引用的情况下复制 sObj 的任何想法?
** 更新:
正如 RichS 提供的链接所指出的,原因似乎是 getter 和 setter 属性不可枚举,因此它们不会被复制。这个问题密切相关(如果我们去问题的根源,或者重复):Copy object with results of getters
我更新了代码:https://jsfiddle.net/vwb04d4f/3/
我手动添加了“可枚举”属性:
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 有关。
【问题讨论】:
github.com/angular/angular.js/issues/5085 @RichS:感谢您找到该链接!这就解释了一切……我们只需要一些解决方案吗?顺便说一句,我使用的是角度 1.4.4。我会尝试测试版。 【参考方案1】:它的发生是因为深/浅:
“惰性复制是浅拷贝和深拷贝的组合。最初复制对象时,使用(快速)浅拷贝。还使用计数器来跟踪有多少对象共享数据。”
请阅读this 或检查此answer 以使其更清晰甚至有角度docs
【讨论】:
【参考方案2】:我在这个问题中找到了解决方案: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。
这个问题有很多解决方案,我测试了其中的大部分,但不是全部。
【讨论】:
以上是关于Javascript:对象设置器和获取器在克隆/复制/扩展后丢失的主要内容,如果未能解决你的问题,请参考以下文章