如何正确扩展 ES6 Map

Jus*_*ein 10 javascript dictionary ecmascript-6

我有一个简单的案例:一个 ES6 Map,我需要向它添加 customget()set()

但是Map是一个内置对象,所以我不确定这样做是否会有任何警告。我试图搜索将 a 子类化是否正确Map,并得到了不一致的结果:尚不清楚规范是否允许它,哪些浏览器/node.js 版本支持它,以及可能产生哪些副作用(以及要涵盖的内容)带测试)。

据我了解,扩展Map功能主要有以下三种方法:

  1. 将其子类化。我已经完成了,它似乎有效。
class CustomMap extends Map{
    get(key){
        return super.get(key);
    }
    set(key, value){
        return super.set(key, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

它的问题:Internet 上的很多文章都指出,扩展内置对象可能会遇到麻烦。大多数是 2016 年初,现在是 2017 年末,在 Chrome 61 中进行测试。也许现在这是一种安全且受支持的方法?

  1. 制作一个包装对象
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
}
Run Code Online (Sandbox Code Playgroud)

最不优雅的解决方案,因为我不仅需要实现getand set,还需要实现所有Map 功能。此外,Wrapper不是Map.

  1. 使用 ES6 代理
const ProxyMap = function(){
    return new Proxy(new Map(), {
        get(target, key){
            return target.get(key)
        }
        set(target, key, value){
            target.set(key, value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

与扩展类一样,不建议应用于Proxy某些内置类型。但同样,自引入Proxy规范以来已经过去了很多时间;也许现在Map可以通过在现代浏览器中代理?

那么,问题来了:Map2017年什么样的扩展方式才是正确且稳健的方式呢?

Ber*_*rgi 7

尚不清楚规范是否允许

这是。从 ES6 开始,所有内置类型都可以使用class语法进行扩展

目前尚不清楚哪些浏览器/node.js 版本支持它

他们需要支持 ES6 类和Map本机。使用转译器通常会破坏它。

1) 子类化。我已经完成了,它似乎有效。

是的,这是正确的方法。

Internet 上的许多文章都指出,扩展内置对象可能会遇到麻烦。大多数是 2016 年初,现在是 2017 年底,在 Chrome 61 中测试。

我不知道,主要参考http://perfectkills.com/extending-native-builtins/是从 2011 年开始的。这些文章通过“扩展内置函数”意味着不同的东西:用自定义对象修改它们的原型对象,例如Map.prototype.getWithDefault = function(…) { … };. 他们不指class … extends …

制作一个包装对象

这也应该没问题。我认为你不一定需要你的实例instanceof Map,如果你需要,你必须遵循Liskov 替换原则。并非键值集合的所有“扩展”都适合。

3) 使用 ES6 Proxy - 不建议将 Proxy 应用于某些内置类型。

事实上,这行不通,或者至少很麻烦。