为什么jQuery的深层复制不能复制描述性属性?

时间:2017-09-26 08:33:08

标签: javascript jquery

在了解Object.defineProperty()时,我正在尝试深度克隆对象。请考虑以下代码段



var obj = {};
Object.defineProperty(obj, 'key', {
  get: () => {return key},
  set: (value) => {
          if (typeof(value) == 'number'){
              key = value;
          }
       }
});

obj.key = 54;
console.log(obj.key);                 // Output: 54
obj.key = ['a', 'b'];
console.log(obj.key);                 // Output: 54

var clone = $.extend(true, {}, obj);

clone.key = 44;
console.log(obj.key, clone.key);      // Output: 54 44
clone.key = 'hello';
console.log(clone.key);               // Output: hello

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

为什么jQuery创建的克隆不能保持对象的原始getter和setter。如果我确实需要这个功能,我怎样才能让深度克隆的对象拥有与父母相同的getter和setter?

2 个答案:

答案 0 :(得分:1)

使用Object.defineProperty使用set的描述符定义属性时,可以为要更改的值添加事件。此事件与对象的引用相关联。

当您使用$.extend时,它的作用是复制其值。

以下是$.extend

的部分代码
for (; i < length; i++) {

  // Only deal with non-null/undefined values
  if ((options = arguments[i]) != null) {

    // Extend the base object
    for (name in options) {
      src = target[name];
      copy = options[name];

如您所见,仅复制值。没有复制描述符的原因可能是,拥有描述符的意图仅针对该对象而不是其子对象。

Object.assign

也共享此行为

var obj = {};
Object.defineProperty(obj, 'key', {
  get: () => {
    return key
  },
  set: (value) => {
    if (typeof(value) == 'number') {
      key = value;
    }
  }
});

obj.key = 54;
console.log(obj.key); // Output: 54
obj.key = ['a', 'b'];
console.log(obj.key); // Output: 54

var clone = Object.assign({}, obj)

clone.key = 44;
console.log(obj.key, clone.key); // Output: 54 44
clone.key = 'hello';
console.log(clone.key); // Output: hello

答案 1 :(得分:0)

我认为问题在于功能的范围。 您无法克隆范围并避免在克隆时决定省略函数的问题。

但我不确定。