【问题标题】:Cloning Non enumerable properties in javascript在javascript中克隆不可枚举的属性
【发布时间】:2021-03-04 18:33:43
【问题描述】:

我在对象中有所有不可枚举的属性,我想克隆那个对象。

我的问题不可枚举属性没有被克隆。

举个例子

 Object.defineProperty(this, 'prop', {
        get: function () {
            return prop;
        },
        set: function (value) {
            prop= value;
        }
    });

   Object.defineProperty(this, 'newprop', {
        get: function () {
            return newprop;
        },
        set: function (value) {
            newprop= value;
        }
    });

例如,我的对象中有以上两个属性使用以下方法进行克隆,我的属性没有被克隆我相信这是因为它们是不可枚举的。

   var newObject = $.extend({},oldObject);
   var newObject= Object.assign({},oldobject);

如何在 javascript 中复制不可枚举的属性。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    如果一个或多个属性不可枚举,您希望如何神奇地自动枚举它们?

    既然你知道他们的名字,你应该这样做:

    var sourceObj = this;
    var targetObj = {};
    
    ["prop", "otherProperty"].forEach(function(property) {
        targetObj[property] = sourceObj[property]; 
    });
    

    或者您可以在定义不可枚举的属性时构建整个属性名称数组:

       var propertyNames = [];
    
       Object.defineProperty(this, 'newprop', {
            get: function () {
                return newprop;
            },
            set: function (value) {
                newprop= value;
            }
        });
        propertyNames.push("newprop"); // <---
    
    
       Object.defineProperty(this, 'newprop2', {
            get: function () {
                return newprop;
            },
            set: function (value) {
                newprop= value;
            }
        });
        propertyNames.push("newprop2"); // <---
    
    propertyNames.forEach(function(property) {
        targetObj[property] = sourceObj[property]; 
    });
    

    替代方法:Object.getOwnPropertyNames

    Object.getOwnPropertyNames() 方法返回一个包含所有 直接在给定对象上找到的属性(可枚举或不可枚举)。

    也许这是最好的方法。 Object.getOwnPropertyNames 获取自己对象属性的名称,无论它们是否可枚举。也就是说,您可以避免构建整个 propertyNames 数组,并且这种方法应该适合您,因为您说过所有属性都不可枚举

    var sourceObj = this;
    var targetObj = {};    
    
    Object.getOwnPropertyNames(sourceObj).forEach(function(property) {
        targetObj[property] = sourceObj[property]; 
    });
    

    【讨论】:

    • 对不起,我有一个对象,所有不可枚举的属性
    • @MaxMaddy 这不会改变答案,不是吗?
    • @MaxMaddy 用另一种方法查看我的更新;P
    • 完美:) 谢谢
    • “替代方法”需要成为这里唯一的解决方案。第一个解决方案是不好的坏习惯!
    【解决方案2】:

    你可以使用Object.definePropertiesObject.getOwnPropertyDescriptors()函数

    Object.defineProperties() 方法直接在对象上定义新属性或修改现有属性,并返回该对象。

    Object.getOwnPropertyDescriptors() 方法返回给定对象的所有自己的属性描述符。

    所以,你可以将原始对象的属性添加到一个空对象中,如下

    var source_obj = this
    var cloned_obj = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source_obj));
    

    【讨论】:

      【解决方案3】:

      我在How to implement Ruby's extend module in JavaScript 有类似的问题。

      而且因为我不想使用迭代将每个方法附加到新对象,所以我能做的最后最好的方法就是这样,欢迎给我任何想法和建议,谢谢。

      class Test {
      
        constructor(name) {
      
          this.name = name;
        }
      
        test1(){
          return this.name + "test1"
        }
      }
      
      const Other = {
        test2: function(){
          return this.name + "test2"
        },
      
        test3: function(){
          return this.name + "test3"
        },
      
        test4: function(){
          return this.name + "test4"
        }
      
      }
      
      var person = new Test("HKE")
      Object.assign(person,Other) //this like object.extend(Module) in ruby
      console.log(person.test1()) // HKEtest1
      console.log(person.test2()) // HKEtest2
      console.log(person.test3()) // HKEtest3
      console.log(person.test4()) // HKEtest4
      
      var house = new Test("Tsao")
      console.log(house.test1())
      console.log(house.test2()) // TypeError: house.test2 is not a function
      console.log(house.test3()) // TypeError: house.test3 is not a function
      console.log(house.test4()) // TypeError: house.test4 is not a function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-07
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        • 2015-02-08
        • 2013-07-29
        • 2012-05-02
        • 2013-09-03
        相关资源
        最近更新 更多