根据我对文档(here和here)的理解,我需要引用内存地址才能使用它:
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
垫片可用:https://github.com/zloirock/core-js#map。我尝试阅读源代码,但它过于整齐抽象(internally使用strong collection which then imports 10 more files)
请回答以下任何一项
foo
以在其上存储一些字符串然后将其用作密钥?答案 0 :(得分:10)
有两种方式可以想到。首先,显然,您可以拥有一系列密钥,并进行线性搜索:
java -jar c:\selenium\selenium-server-standalone-2.21.0.jar -htmlSuite "*firefox" "http://localhost:8080" "c:\test\my-test-suite.html" "c:\test\my-test-result.html"

第二个选项是添加一个特殊的"键"标记到用作关键字的对象:
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>")
&#13;
与第一个选项不同,第二个选项是O(1)。通过使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>")
不可写/可枚举,可以更准确地完成它。此外,每个uid
应该有自己的&#34; uid&#34; name(可以在Map构造函数中轻松设置)。
答案 1 :(得分:7)
技巧是存储在一个数组中并通过迭代和使用严格比较在O(n)时间内执行查找 - 而不是使用真正的哈希函数,这将是O(1)查找。例如,考虑一下:
var myObj = {};
var someArray = [{}, {}, myObj, {}];
console.log(someArray.indexOf(myObj)); // returns 2
以下是我在另一个答案中的实现:Javascript HashTable use Object key
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)];
}
};
}
答案 2 :(得分:0)
查看我的polyfill here。我不是在宣传我的polyfill,而是我说的是它是我还没有找到的最简单,最直接的,因此它最适合学习和教育分析。基本上,它的工作原理是它使用键的查找表和相应的值表,如下图所示。
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(){}
在内部,每个项目都存储在不同的索引中,或者至少这是我喜欢的方式。这也类似于浏览器在内部实现它的方式。不幸的是,我已经看到一些其他的polyfill试图将密钥存储在对象本身上,并且乱用所有内部方法来隐藏它,导致整个网页运行速度慢10000%并且地图速度太快以至于几乎需要只需设置并获取新属性就足够了。另外,我无法理解他们只是试图修补所有内部方法(例如hasOwnProperty
)的无数个小时。
至于我的polyfill的工作方式和原因,javascript对象存储在内存中的不同位置。这就是为什么javascript对象数组上的[] !== []
和indexOf正常工作的原因。这是因为它们不是同一个数组。