1

I would like to create some custom JS syntax. Is there a way I can write a method so that the following would work:

var someDict = {"abc": 1, "efg": 2}
someDict.keys
someDict.values

instead of:

Object.keys(someDict)
Object.values(someDict)

In Swift this sort of thing can be done via extensions, I'm just wondering if there's a way in JS.

2 Answers 2

3

You can create an object with getters:

class ObjWithKeyValGetters {
  constructor(obj) {
    Object.assign(this, obj);
  }
  get keys() {
    return Object.keys(this);
  }
  get values() {
    return Object.values(this);
  }
}
const myObj = new ObjWithKeyValGetters({"abc": 1, "efg": 2});
console.log(myObj.keys);
console.log(myObj.values);

Sign up to request clarification or add additional context in comments.

2 Comments

Awesome thanks! So basically I just create a custom class for this sort of thing. There isn't a way to extend the existing object class?
You can mutate the built-in object prototypes, but that's very bad practice - that sort of thing is what got us debacles like this one.
0

Maybe you are looking for prototype . you can add new methods to Object with prototype like :

var current = Object.prototype.valueOf;

// Since my property "-prop-value" is cross-cutting and isn't always
// on the same prototype chain, I want to modify Object.prototype: 
Object.prototype.valueOf = function() {
  if (this.hasOwnProperty('-prop-value')) {
    return this['-prop-value'];
  } else {
    // It doesn't look like one of my objects, so let's fall back on 
    // the default behavior by reproducing the current behavior as best we can.
    // The apply behaves like "super" in some other languages.
    // Even though valueOf() doesn't take arguments, some other hook may.
    return current.apply(this, arguments);
  }
}

as modified MDN pollyfill for Object.keys:

Object.prototype.pollufillKeys = (function() {
    'use strict';
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({
            toString: null
        }).propertyIsEnumerable('toString'),
        dontEnums = [
            'toString',
            'toLocaleString',
            'valueOf',
            'hasOwnProperty',
            'isPrototypeOf',
            'propertyIsEnumerable',
            'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function(obj) {
        if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {
            throw new TypeError('Object.keys called on non-object');
        }

        var result = [],
            prop, i;

        for (prop in obj) {
            if (hasOwnProperty.call(obj, prop)) {
                result.push(prop);
            }
        }

        if (hasDontEnumBug) {
            for (i = 0; i < dontEnumsLength; i++) {
                if (hasOwnProperty.call(obj, dontEnums[i])) {
                    result.push(dontEnums[i]);
                }
            }
        }
        return result;
    };
}());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.