JS: Modify Value/Pair in JS Object

后端 未结 4 1744
一个人的身影
一个人的身影 2021-01-22 17:10

I\'m trying to work out the best way to modify an object without writing out a similar object three times. So I have these three objects:

var object1 = {
    sta         


        
相关标签:
4条回答
  • 2021-01-22 17:35

    You can set the common properties to a prototype object. For Example:

    function ObjectMaker (typeVal) {
      this.type = typeVal;
    }
    
    ObjectMaker.prototype.start = "start";
    ObjectMaker.prototype.end = "end";
    
    var object1 = new ObjectMaker("1");
    var object2 = new ObjectMaker("2");
    

    gives

    > object1.start
    "start"
    > object1.end
    "end"
    > object1.type
    "1"
    

    You could pass in an object to the maker function if number of variables are more.

    Since the prototype is shared across objects, you will have a lighter memory footprint than having the same on each object.

    0 讨论(0)
  • 2021-01-22 17:35

    Create a function

    function createObj(start,end,type){
        return  {
            start : start,
            end   : end,
            type  : type
        }
    }
    var object1 = createObj(start,end,1);
    var object2 = createObj(start,end,2);
    var object3 = createObj(start,end,3);
    
    // if start and end are in scope to the function 
    function createObj(type){
        return  {
            start : start,
            end   : end,
            type  : type
        }
    }
    var object1 = createObj(1);
    var object2 = createObj(2);
    

    UPDATE in lieu of the various answers given.

    As there are three answers that are all valid I will present speed tests from jperf.com for both creation and object use.

    The test can be found Here jsperf.com

    Testing in Chrome 47.0.2526.27 on Windows Server 2008 R2 / 7

    Creation Tests

    • Create via Object Assign : 84,270 ±0.94%
    • Create via function : 18,267,444 ±1.72%
    • Create via new and prototype :7,886,088 ±1.69%
    • Create inline (literals) : 29,203,404 ±1.34% Fastest Create

    Use tests.

    • Use for Object Assign : 266,301,340 ±2.45%
    • Use for function created : 301,185,103 ±1.78% Fastest Use
    • Use for new and prototype created : 18,628,401 ±3.14%
    • Use for inline created : 272,981,998 ±2.74%

    As can be seen object.assign is very slow on when it come to creating object, but holds its own when the objects are being used.

    Creating prototypes is about the worst that you can do. Though not as slow as Object assign it seriously suffers when it comes to using objects created this way. Running at below one tenth the speed of the next fastest.

    As expected creating objects inline is by far the fastest, though not the most convenient. Yet it was not the fastest when it came to use which is a bit of a surprise.

    The fastest for use is creation via function. Though I do not know why and suspect it has to do with V8's optimisation.

    Each method has its pros and cons and should be judged on its use and project standards and conventions. In most cases speed is not an issue. Though keep in mind "green coding" favours code that takes the minimum number of cpu cycles, of which execution speed can give a good estimate of. Saving cycles saves power, money, and the lovely world we live on.

    Below is the code for the tests. I think I was fair on all four methods.

    //================================================================
    // Create via Object Assign
    var object1 = {
        start: start,
        end: end,
        type: 1
    };
    
    var object2 = Object.assign({}, object1, {type: 2});
    var object3 = Object.assign({}, object1, {type: 3});
    
    //================================================================
    //Create via function
    function createObj(type){
        return  {
            start : start,
            end   : end,
            type  : type
        }
    }
    var object1 = createObj(1);
    var object2 = createObj(2);
    var object3 = createObj(3);
    
    //================================================================
    //Create via new and prototype
    function ObjectMaker (typeVal) {
      this.type = typeVal;
    }
    
    ObjectMaker.prototype.start = start;
    ObjectMaker.prototype.end = end;
    
    var object1 = new ObjectMaker(1);
    var object2 = new ObjectMaker(2);
    var object2 = new ObjectMaker(3);
    
    //================================================================
    // Create inline objects
    var object1 = {
        start: start,
        end: end,
        type: 1
    };
    var object2 = {
        start: start,
        end: end,
        type: 2
    };
    var object3 = {
        start: start,
        end: end,
        type: 3
    };
    

    Use tests.

    //================================================================
    // Use case for object created with Object.assign
    objectB2.end += 1;
    objectB2.start += 1;
    objectB2.type += 1;
    
    //================================================================
    // Use case for object create with new
    objectA1.end += 1;
    objectA1.start += 1;
    objectA1.type += 1;
    
    //================================================================
    // Use case for function created object
    objectC1.end += 1;
    objectC1.start += 1;
    objectC1.type += 1;
    
    //================================================================
    // Use of literal object create
    objectD1.end += 1;
    objectD1.start += 1;
    objectD1.type += 1;
    

    Setup code

      Benchmark.prototype.setup = function() {
        // assuming start and end are global
        var start = 0;
        var end = 10;
    
        // Prototype Method
        // object for use test 
        function ObjectMakerA (typeVal) {
          this.type = typeVal;
        }
        ObjectMakerA.prototype.start = start;
        ObjectMakerA.prototype.end = end;
        var objectA1 = new ObjectMakerA(1);
    
        // Object assign method 
        // for use test
        var objectB1 = {
            start: start,
            end: end,
            type: 1
        };
        // object to use
        var objectB2 = Object.assign({}, objectB1, {type: 2});
    
        // Anonymous object
        // for use test
        function createObj1(type){
            return  {
                start : start,
                end   : end,
                type  : type
            }
        }
        // object for use test
        var objectC1 = createObj1(1);
    
        // Literal object for use test
        var objectD1 = {
            start: start,
            end: end,
            type: 1
        };
      };
    
    0 讨论(0)
  • 2021-01-22 17:41

    I assume you want to create multiple sets of objects with the same start/end pair, but different types.

    One approach would be write a function, to which you'd pass a start/end pair, and which returns a function to create an object with a particular type:

    function make_creator(start, end) {
      return function(type) {
        return { start, end, type };
      };
    }
    

    Now you can create your objects as

    var creator = make_creator(start, end);
    var object1 = creator(1);
    var object2 = creator(2);
    var object3 = creator(3);
    

    In this case, you can think of the make_creator function as "storing" the values of start and end for use within the returned closure. It's conceptually related to "storing" them within the "template" proposed in another answer.

    Prototypes

    Let's consider using prototypes. It's not usually a good idea idea to place values in prototypes. You are likely to shoot yourself in the foot when you try to set the property and end up creating a sort of shadow value on the instance. Any performance (memory) differences will be miniscule unless you have a million objects, and will outweighed by the cost of finding the property on the prototype chain. More importantly, if you want multiple sets of objects with the same start/end pair, you'd have to create separate prototypes for each.

    Performance

    I'm not quite sure why or when we all started worrying quite so much about performance. The bottom line is that the difference in performance (either memory or speed) between any alternatives is going to be miniscule. (The exception is if you are creating millions or tens of millions of these objects.) The guiding principle should be to find an approach which is easy to write, easy to read, and easy to maintain. If you are creating tens of millions of objects, and you determine by profiling your program that this particular area is the bottleneck, then that would be the time to go back and optimize it.

    0 讨论(0)
  • 2021-01-22 17:53

    If we are dealing with primitives for all of these properties you can use Object.assign with no worries

    var objectTemplate = {
        start: start,
        end: end,
        type: 0
    };
    
    var object1 = Object.assign({}, objectTemplate, {type: 1})
        object2 = Object.assign({}, objectTemplate, {type: 2}),
        object3 = Object.assign({}, objectTemplate, {type: 3});
    

    You don't have to use a template object, you could jump straight into the first object (see previous revision), but as @Blindman67 points out: if you can't guarantee an object will be as you expect then it may be better to use a template which you can guarantee.

    0 讨论(0)
提交回复
热议问题