I have a simple case: a ES6 Map
, and I need to add custom get()
and set()
to it.
But Map
is a built-in object, so I'm not sure whether there would be any caveats in doing so. I've tried to search whether it is correct to subclass a Map
, and got inconsistent results: it is unclear whether it's allowed by specification, what browser/node.js versions support it, and what side-effects are possible (and what to cover with tests).
As I understand, there are three main approaches to extend Map
functionality:
- Subclass it. That I've done, and it seems like it works.
class CustomMap extends Map{ get(key){ return super.get(key); } set(key, value){ return super.set(key, value); }}
Problem with it: a lot of articles on the Internet state that you can run into troubles with extending built-in objects. Most are early 2016, and now is late 2017, testing in Chrome 61. Maybe now it is a safe and supported way of doing it?
- Make a wrapper object
const Wrapper = function(){ this._map = new Map(); this.get = (key) => {return this._map.get(key);} this.set = (key, value) => {this._map.set(key, value);} ... everything else}
The least elegant solution, as I need to implement not just get
and set
, but all of Map functionality. Also, Wrapper
is not an instance of Map
.
- Use ES6 Proxy
const ProxyMap = function(){ return new Proxy(new Map(), { get(target, key){ return target.get(key) } set(target, key, value){ target.set(key, value); } }}
As with extending a class, it is unadvisable to apply Proxy
to some built-in types. But again, a lot of time passed since introducing the Proxy
specifications; maybe now Map
could by proxied in modern browsers?
So, the question is: what way of extending a Map
is a correct and robust way in 2017?