1

How do I remove the first property of an object like:

var obj = { x:1, y:2, z:3 };

so that obj becomes:

{ y:2 , z:3 };

This approach doesn’t work for me:

delete obj.x

as I don't know any details about the object’s properties.

I just need to delete the first property.

user1063287
  • 10,265
  • 25
  • 122
  • 218
27mdmo7sn
  • 499
  • 2
  • 6
  • 15
  • 1
    That Javascript is invalid. When you fix it, by the way, [Javascript don't guarantee property order](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order). What you see as "first property" can be another property on whatever environment. Use arrays or `Map`, which is something like an object with keys and values, but with property insertion order guarantee. – Jorge Fuentes González Aug 17 '19 at 16:05
  • @JorgeFuentesGonzález no they are ordered, but not in the sequence they are inserted – Code Maniac Aug 17 '19 at 16:08
  • [`Property order of object`](https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015/) – Code Maniac Aug 17 '19 at 16:10
  • Object order isn't guaranteed, but all modern browsers handle object key ordering in the same way – Damon Aug 17 '19 at 16:12
  • @CodeManiac Javascript specs say that property order is not guaranteed. Other thing is that most engines, internally, save them in some kind of order, but if they suddenly change how they work internally because of whatever reason and you get different result, you can't complain as they are still under Javascript specs. If you want true insertion order with specs support, use `Map()` instead. For example, when a `sort()` function returns the same value for 2 entries, order is not guaranteed to be the same in different engines. And that's what happens with IE<->Chrome. This is the same. – Jorge Fuentes González Aug 17 '19 at 16:13
  • @paulpro oh really? Could you prove your claim please? – Jonas Wilms Aug 17 '19 at 16:16
  • @Jorge IE isn't ES2015 compliant. – Jonas Wilms Aug 17 '19 at 16:17
  • I'm using these codes in node environment , not in browser :) – 27mdmo7sn Aug 17 '19 at 16:18
  • @JonasWilms Yes but is a browser still used nowadays and not deprecated by Microsoft, like some other browsers around there. Not a major %, but still a % of hits. Depends on what you are doing. For example, I spend a lot of time testing IE11 as we develop some software for some companies that have Windows Server images with IE11 default browser, which they refuse to change, so we have a really big % of IE11 users. Kinda painful sometimes, but if wasn't for those companies, I won't focus on IE11 anymore. – Jorge Fuentes González Aug 17 '19 at 16:59

2 Answers2

3

In modern JS environments (ES2015+), the ordering of keys is well-defined so you should be able to do something like this:

const keys = Reflect.ownKeys(obj); // thanks to Paulpro for improving this!
if (keys.length) delete obj[keys[0]];

Note that delete won't always work, but for most "normal" objects this should do what you need.

Since there's some contention over the ordering of JS objects, here's the ECMAScript standard: https://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys

CollinD
  • 7,304
  • 2
  • 22
  • 45
  • 2
    Order is not specified for Object.keys, you would need to use Reflect.ownKeys to get a specific order – Paul Aug 17 '19 at 16:14
  • 1
    "The ordering of the properties is the same as that given by looping over the properties of the object manually." from the MDN docs. Am I misunderstanding that `looping over the object manually` does not imply using the `ownpropertykeys` internal method? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – CollinD Aug 17 '19 at 16:15
  • 2
    Yes, you are. That's talking about `for..in` which also has an unspecified order (but must be the same order as Object.keys). – Paul Aug 17 '19 at 16:17
  • 2
    This sums it up pretty well: https://stackoverflow.com/a/30919039/772035 – Paul Aug 17 '19 at 16:21
1

First of all: Javascript (ES5) don't guarantee property order. There are still browsers running on ES5 (IE11 ahem, although they keep property order partially) so depending on your environment, I recommend you to follow this rule.

That's a really really important point.

Now, after you understood why you shouldn't do that, I'll explain a way to remove the first property (whatever first is in your current environment).

You can do it two ways. The most performant way in IE11 and Firefox is this one:

for (var i in obj) {
    delete obj[i];
    break;
}

And also you can do:

delete obj[Object.keys(obj)[0]];

Which is less performant on IE and Firefox but better on Chrome (performance test below):

function newList() {
    var objs = [];
    var props = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ";
    for (var i = 0; i < 200000; i++) {
        var obj = {};
        for (var ii = 0; ii < props.length; ii++) {
            obj[props[ii]] = ii;
        }
        objs.push(obj);
    }
    return objs;
}

var objs = newList();
console.time("Object.keys()");
for (var i = 0; i < objs.length; i++) {
    delete objs[i][Object.keys(objs[i])[0]];
}
console.timeEnd("Object.keys()");

objs = newList();
console.time("for...in");
for (i = 0; i < objs.length; i++) {
    for (var j in objs[i]) {
        delete objs[i][j];
        break;
    }
}
console.timeEnd("for...in");

NOTE: Woah, surprise for me. In V8 Object.keys() works pretty well right now. But in Firefox and IE11 preformance is still worse.

Chrome:
enter image description here

IE11:
enter image description here

Firefox:
enter image description here

Not tested more browsers as those 3 are the only ones I develop for (yeah... IE11...). Surprised also that IE11 has better performance than Firefox. Usually is way worse.

Seems that the overhead for Object.keys() is when creating the array, but the overall performance changes with the amount of properties on both ways. Thank you for telling me to do some tests Jonas Wilms.

Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64
  • To my knowledge, javascript objects are ordered as of ES2015. This is a pretty critical fact for things like mongoose's interface with mongodb where ordering of keys within objects is important for things like indices. – CollinD Aug 17 '19 at 16:12
  • Thanks @Jorge , this is the correct answer , however I have another related question - in the same way , how to change the value of the first property ? – 27mdmo7sn Aug 17 '19 at 16:17
  • 1
    "the most performant way is..." if you make that claim, prove it with a real world performance comparison. – Jonas Wilms Aug 17 '19 at 16:19
  • I thought it was pretty obvious. The more properties an object has, the worse is for the `Object.keys()` method. To be safe, the `for...in` way is the way to go to be sure property count is not a problem. Going to edit the answer by the way. – Jorge Fuentes González Aug 17 '19 at 16:25
  • @27mdmo7sn Just change the `delete obj[i];` for `obj[i] = 123;` for example. – Jorge Fuentes González Aug 17 '19 at 16:26
  • Done @JonasWilms. Got interesting results actually. – Jorge Fuentes González Aug 17 '19 at 17:04
  • 1
    Yes, browsers perform optimizations of all kinds at various levels. I'm always cautious with the usage of *faster* cause of that. – Jonas Wilms Aug 17 '19 at 17:30