ES6 Map垫片如何工作 [英] How do the ES6 Map shims work
问题描述
基于我对文档的理解(此处和此处),则需要引用内存地址才能使其正常工作:
Based on my understanding of the docs (here and here) one would need a reference to the memory address for it to work:
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中是).
This is because JavaScript object {}
keys can only be strings (at least in ES5).
但是我看到Map
垫片可用: https://github.com/zloirock/core-js#map .我尝试阅读源代码,但其源头太整齐了(内部使用强集合,然后再导入10个文件)
Yet I see Map
shim being available : https://github.com/zloirock/core-js#map. I tried reading the source but its too neatly abstracted (internally uses strong collection which then imports 10 more files)
请回答以下任何一项
- 是否有一个简单的技巧,它真的可以完成(不带字符串化)吗?
- 也许它会变异
foo
在其上存储一些字符串,然后将其用作键? - 还有什么可能是我在阅读文档时出错了吗?
- Is there a simple trick to it and can it truly even be done (without stringification)?
- Perhaps it mutates
foo
to store some string on it and then uses that as the key? - Something else and maybe I am reading the docs wrong?
推荐答案
有两种方法.首先,显然,您可以拥有一个键数组,并进行线性搜索:
There are two ways that come to mind. First, obviously, you can have an array of keys, and search it linearly:
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>")
第二个选项是向用作键的对象添加特殊的键"标记:
The second option is to add a special "key" marker to an object which is used as a key:
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构造函数中轻松设置).
Unlike the 1st option, the second one is O(1). It can be done more accurately by making uid
non-writable/enumerable. Also, each Map
should have its own "uid" name (this can be easily set up in the Map constructor).
这篇关于ES6 Map垫片如何工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!