25

I'm looking at the stage 3 proposal of Object.values/Object.entries and I'd really like to use it in my current JavaScript project.

However, I can't figure out whether there's any Babel preset which supports it. Since the GitHub repository linked above says it's a stage 3 proposal, I assumed it would be part of babel-preset-stage-3, but it seems not.

Is there any Babel preset (or even plugin?) that lets me use Object.entries today?

damd
  • 6,116
  • 7
  • 48
  • 77
  • 1
    https://babeljs.io/docs/usage/polyfill/ , https://github.com/zloirock/core-js#ecmascript-7-proposals – Felix Kling Jan 29 '16 at 17:13
  • @FelixKling: Thank you, but I'm afraid I don't really know what to do with the information you linked! – damd Jan 29 '16 at 17:15
  • 2
    Babel polyfill simply uses core-js, but I'm not sure which features. If you just want to support `Object.entries`, simply load core-js' polyfill for that. – Felix Kling Jan 29 '16 at 17:17
  • @FelixKling: I finally figured out how to use it! Please add your comment as an answer and I'll happily accept it! :) – damd Jan 29 '16 at 18:03

4 Answers4

33

Using babel, installing

  1. babel-preset-env
  2. babel-plugin-transform-runtime

gives support for Object.values/Object.entries as well as other *ES20** functionality.

As per recommendation by the modules, configure .babelrc with the following:

{
  "plugins": ["transform-runtime"],
  "presets": ["env"]
}
psv
  • 688
  • 6
  • 19
  • 4
    I see no mention of `Object.entries` support in https://babeljs.io/docs/plugins/preset-es2017/. Was support moved to another preset? https://github.com/bettiolo/babel-preset-es2017/issues/37 seems to confirm this functionality is not covered by the preset. – Gili Jan 03 '17 at 23:59
  • 6
    I was targeting a browser. In that context, you are required to use https://babeljs.io/docs/usage/polyfill/. Can you please update the answer to address what users should do for node vs browser? – Gili Jan 05 '17 at 17:02
  • babel-polyfill do support `Object.entries` as of now, when targeting a browser you just need to include `import "babel-polyfill";` at your applications entry point (root index.js) – Niveditha Karmegam Jun 13 '18 at 12:08
  • 2
    babel-preset-es2017 is deprecated now, use instead babel-preset-env – Nati Lara-Diaz Jul 05 '19 at 13:37
14

What I did was install core-js and then just call this at the top of my file:

require('core-js/fn/object/entries');

This made Object.entries available. Credits to @FelixKling.

Update

In core-js@3, the import path has changed:

require('core-js/features/object/entries');
Paul Razvan Berg
  • 16,949
  • 9
  • 76
  • 114
damd
  • 6,116
  • 7
  • 48
  • 77
6

Update:

As noted in the comments, you can improve performance by using the map function instead of reduce.

Please note that the code is case-sensitive (object != Object).

// Object.values

var objectToValuesPolyfill = function(object) {
    return Object
             .keys(object)
             .map(
                  function(key) {
                    return object[key];
                  }
              );
}

Object.values = Object.values || objectToValuesPolyfill;

// Object.entries

var objectToEntriesPolyfill = function(object) {
    return Object
             .keys(object)
             .map(
                  function(key) {
                    return [key, object[key]];
                  }
              );
}

Object.entries = Object.entries || objectToEntriesPolyfill;

Usage:

// es6

Object.values = Object.values || (x => Object.keys(x).map(k => x[k]));
Object.entries = Object.entries || (x => Object.keys(x).map(k => [k, x[k]]));

// es5

Object.values = Object.values || function(x){ 
    return Object.keys(x).map(function(k){ 
        return x[k];
    })
};

Object.entries = Object.values || function(x){ 
    return Object.keys(x).map(function(k){ 
        return [k, x[k]];
    })
};


const a = {
  key: "value",
  bool: true,
  num: 123
}

console.log(
  Object.values(a)
)

console.log(
  Object.entries(a)
)
Randy
  • 9,419
  • 5
  • 39
  • 56
  • 3
    You can actually use `map` instead of `reduce` here, which is a bit simpler: `.map(key => object[key])` (where `object` is your `x`). Also, I assume you are going for performance over readability when giving the variables one letter names, but since this is an educational answer I'd suggest using logical names and add a comment about shortening them for performance. – ArneHugo Mar 17 '17 at 08:00
0

Another alternative solution that I find in the end of 2020, that works for IE11.

npm install --save-dev babel-plugin-transform-es2017-object-entries

and then add to the package.json

"babel": {
    "plugins": [
        "transform-es2017-object-entries"
    ]
}
elfan
  • 1,131
  • 6
  • 11