Javascript:克隆/复制/扩展后,对象的setter和getter丢失 [英] Javascript: object's setter and getter is lost after clonning / copying / extending

查看:126
本文介绍了Javascript:克隆/复制/扩展后,对象的setter和getter丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够复制 getter 设置功能。



注意:这个问题与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 =值;
},
get val(){
返回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);

输出:

 设置:100 
值:200
设置:300
值:300

为什么在 angular.copy之后不再触发 set val?如您所见,该值已正确存储。



angular.extend保留引用,因此更新sExt会更新sObj,我不希望这样做。 / p>

我正在复制作用域对象,然后将其传递给控制器​​(模态):

  $ modal.open({
动画:true,
templateUrl:'/html/settings.html',
控制器:'ModalInstanceCtrl',
背景:否,
解析:{
config:function(){
var cfgcpy = {};
angular.copy($ scope.config,cfgcpy);
返回cfgcpy;
}
}
})。result.then(function(res){
ok_func(res);
close_func();
} ,function(){
close_func();
});

angular.module('app')。controller('ModalInstanceCtrl',函数($ scope,$ modalInstance,config){
$ scope.config = config;
。 ..
});

关于如何在不丢失 set和 get且不保留引用的情况下复制sObj的任何想法?



**更新:



正如RichS提供的链接所指出的,原因似乎是getter和setter属性不可枚举,因此不会被复制。这个问题是密切相关的(或者如果是问题的根源,则是重复的):复制具有吸气剂结果的对象



我更新了代码: https://jsfiddle.net/vwb04d4f/3/



我手动添加了可枚举属性:

  var SomeObj = function(){
var obj = {
_val:0
}
对象.defineProperty(obj, val,{
可枚举:true,
set:函数(值){
out( Set: +值);
this._val = value;
},
get:function(){
返回this._val;
}
});
返回对象;
};

但是,无论是扩展(从空对象开始)还是复制都不能真正完成这项工作。



**更新2 **



因为这个问题不仅与

解决方案

我在以下问题中找到了解决方案:

  function cloneObject(source){
var key,value;
var clone = Object.create(source);

for(输入源中的密钥){
if(source.hasOwnProperty(key)=== true){
value = source [key];

if(value!== null&& typeof value === object){
clone [key] = cloneObject(value);
} else {
clone [key] = value;
}
}
}
返回克隆;
}

在此处查看更新的代码: https://jsfiddle.net/vwb04d4f/6/



如您所见,则不需要枚举。到目前为止,这段代码似乎已经解决了我的问题。



这个问题有很多解决方案,我测试了其中大多数,但不是全部。


I would like to be able to copy an object keeping getter and setter functionality.

NOTE: This question is about angularjs but it may apply to many other frameworks as well.

Code available at: 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);

Output:

Set: 100
Value:200
Set: 300
Value: 300

Why "set val" is not triggered anymore after "angular.copy" ? As you can see, the value is correctly stored.

"angular.extend" keeps the references, so updating sExt will update sObj, which I don't want.

I'm copying an scope object before passing it into a controller (modal):

    $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;
  ...
});

Any ideas on how to copy sObj without loosing "set" and "get" and without keeping references?

** UPDATE:

As pointed by the link provided by RichS, it seems that the reason is that getter and setter properties are not enumerable and thus they are not copied over. This question is closely related (or duplicated if we go to the source of the problem): Copy object with results of getters

I updated the code: https://jsfiddle.net/vwb04d4f/3/

I added manually the "enumerable" property:

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;
};

However neither extend (from empty object) or copy do actually the job. Perhaps am I missing something?

** UPDATE 2 **

As this problem is not just related to angularjs.

解决方案

I found a solution in this question: 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;
}

See the updated code here:https://jsfiddle.net/vwb04d4f/6/

As you can see, "enumeration" is not required. So far this code seems to have solved my problem. Thanks goes to Steven Vachon.

There are plenty of solutions in that question, I tested most of them but not all.

这篇关于Javascript:克隆/复制/扩展后,对象的setter和getter丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆