Cloning Non enumerable properties in javascript

后端 未结 2 561
孤街浪徒
孤街浪徒 2020-12-21 02:27

I have all non - enumerable properties in object, I want to clone that object.

My problem non-enumerable properties are not getting cloned.

Take below exampl

相关标签:
2条回答
  • 2020-12-21 02:46

    I have a similar question in How to implement Ruby's extend module in JavaScript.

    And because I don't wanna use iterate attach each method to new object, so the final best way I can do is like that, welcome give me any idea and suggestion, thanks.

    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
    
    0 讨论(0)
  • 2020-12-21 02:56

    If one or more properties aren't enumerable, how do you want to auto-magically enumerate them?

    Since you know their names, you should do something like this:

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

    Or you can build the whole property name array whenever you define a non-enumerable 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]; 
    });
    

    Alternate approach: Object.getOwnPropertyNames

    The Object.getOwnPropertyNames() method returns an array of all properties (enumerable or not) found directly upon a given object.

    Maybe this is the best approach. Object.getOwnPropertyNames gets the name of own object's properties either if they're enumerable or not. That is, you can avoid building the whole propertyNames array, and this approach should be fine with you because you said that all properties aren't enumerable:

    var sourceObj = this;
    var targetObj = {};    
    
    Object.getOwnPropertyNames(sourceObj).forEach(function(property) {
        targetObj[property] = sourceObj[property]; 
    });
    
    0 讨论(0)
提交回复
热议问题