Javascript: объект setter и getter теряются после клонирования/копирования/расширения - javascript


1

Я хотел бы иметь возможность копировать объект getter и setter.

ПРИМЕЧАНИЕ. Этот вопрос касается угловых символов, но может применяться и ко многим другим фреймворкам.

Код доступен по адресу: 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

Почему "set val" больше не запускается после "angular.copy"? Как вы можете видеть, значение правильно сохранено.

"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 без потери "набора" и "получить" и без сохранения ссылок?

** ОБНОВЛЕНИЕ:

Как указано ссылкой, предоставленной RichS, кажется, что причина в том, что свойства getter и setter не перечислимы и, следовательно, они не копируются. Этот вопрос тесно связан (или дублируется, если мы идем к источнику проблемы): Скопировать объект с результатами геттеров

Я обновил код: 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 **

Поскольку эта проблема не просто связана с угловыми.

  •  7
  •  2
  • 8 фев 2020 2020-02-08 08:05:53

2 ответа

0

это происходит из-за глубокого/мелкого:

"Леновая копия - это комбинация как мелкой, так и глубокой копии. При первоначальном копировании объекта используется (быстрая) мелкая копия. Счетчик также используется для отслеживания того, сколько объектов обменивается данными".

Прочитайте этот или проверьте этот ответ, чтобы сделать его более понятным или даже angular docs

  • 8 фев 2020 2020-02-08 08:05:54
3

Я нашел решение в этом вопросе: Каков наиболее эффективный способ глубокого клонирования объекта в 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/

Как вы можете видеть, "перечисление" не требуется. Пока этот код, похоже, решил мою проблему. Спасибо, Стивен Вачон.

В этом вопросе есть много решений, я тестировал большинство из них, но не все.

  • 8 фев 2020 2020-02-08 08:05:54