首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES6映射如何工作?

ES6映射如何工作?
EN

Stack Overflow用户
提问于 2016-03-09 23:17:38
回答 3查看 2.4K关注 0票数 15

根据我对文档(这里这里)的理解,需要引用内存地址才能工作:

代码语言:javascript
复制
const foo = {};
const map = new Map();
map.set(foo,'123');  // Can only be done if memory address of `foo` is known. Any other shimming would require stringification of foo

这是因为JavaScript对象{}键只能是字符串(至少在ES5中是这样)。

然而,我看到Map shim是可用的:https://github.com/zloirock/core-js#map。我试着阅读源代码,但它的抽象过于简洁(内部使用强集合,然后再导入10个文件。)

问题

请回答以下任何一项

  • 它是否有一个简单的窍门,甚至可以真正做到(没有紧张)?
  • 也许它会变异foo来在上面存储一些字符串,然后使用它作为键呢?
  • 还有别的事也许我看错了文档?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-09 23:40:30

我想到了两种方法。首先,很明显,您可以有一个键数组,然后线性地搜索它:

代码语言:javascript
复制
Map1 = {
    keys: [],
    values: [],
};

Map1.set = function(key, val) {
    var k = this.keys.indexOf(key);
    if(k < 0)
        this.keys[k = this.keys.length] = key;
    this.values[k] = val;
};

Map1.get = function(key) {
    return this.values[this.keys.indexOf(key)];
};


foo = {};
bar = {};

Map1.set(foo, 'xxx');
Map1.set(bar, 'yyy');

document.write(Map1.get(foo) + Map1.get(bar) + "<br>")

第二个选项是向用作键的对象添加一个特殊的“键”标记:

代码语言:javascript
复制
Map2 = {
    uid: 0,
    values: {}
};

Map2.set = function(key, val) {
    key = typeof key === 'object'
        ? (key.__uid = key.__uid || ++this.uid)
        : String(key);
    this.values[key] = val;
};

Map2.get = function(key) {
    key = typeof key === 'object'
        ? key.__uid
        : String(key);
    return this.values[key];
};


foo = {};
bar = {};

Map2.set(foo, 'xxx');
Map2.set(bar, 'yyy');

document.write(Map2.get(foo) + Map2.get(bar) + "<br>")

与第一个选项不同,第二个选项是O(1)。通过使uid不可写/可枚举,可以更准确地完成这一任务。另外,每个Map都应该有自己的"uid“名称(这可以很容易地在Map构造函数中设置)。

票数 11
EN

Stack Overflow用户

发布于 2016-03-09 23:39:22

诀窍是通过迭代和使用严格的比较来存储数组并在O(n)时间内执行查找,而不是使用真正的散列函数,即O(1)查找。例如,考虑以下几点:

代码语言:javascript
复制
var myObj = {};

var someArray = [{}, {}, myObj, {}];

console.log(someArray.indexOf(myObj)); // returns 2

以下是另一个答案的实现:Javascript使用对象键

代码语言:javascript
复制
function Map() {
    var keys = [], values = [];

    return {
        put: function (key, value) {
            var index = keys.indexOf(key);
            if(index == -1) {
                keys.push(key);
                values.push(value);
            }
            else {
                values[index] = value;
            }
        },
        get: function (key) {
            return values[keys.indexOf(key)];
        }
    };
}
票数 8
EN

Stack Overflow用户

发布于 2018-03-22 21:25:43

看看我的多填充这里。我不是在宣传我的填充物,而是说它是我迄今所发现的最简单、最直截了当的,因此它最适合学习和教育分析。基本上,它的工作原理是对键使用查找表,并使用相应的值表,如下所示。

代码语言:javascript
复制
var k = {}, j = [], m = document, z = NaN;
var m = new Map([
    [k, "foobar"], [j, -0xf], [m, true], [z, function(){}]
]);




Index      Key                 Value
##### ################    ################
0.    k ({})              "foobar"
1.    j ([])              -15
2.    m (Document)        true
3.    z (NaN)             function(){}

在内部,每个项都存储在不同的索引中,或者至少我喜欢这样做。这也类似于浏览器内部实现它的方式。不幸的是,我看到了一些其他的填充方法试图将密钥存储在对象本身上,并使用所有内部方法来隐藏它,结果导致整个网页运行速度慢了10000%,而地图速度太慢,仅仅设置和获得新属性就需要将近一毫秒的时间。另外,我不知道他们花了多少个小时,只是为了修补所有的内部方法,比如hasOwnProperty

至于如何和为什么我的多边形填充工作,javascript对象存储在一个不同的地方,在内存中。这就是javascript对象数组上的[] !== []和indexOf能够正常工作的原因。这是因为它们不是同一个数组。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35904604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档