Как работают прокладки ES6 Map

Основываясь на моем понимании документов (здесь и здесь), нужна ссылка на адрес памяти для работы:

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. Я пробовал читать источник, но его слишком аккуратно абстрагировался (внутренне использует сильную коллекцию, которая затем импортирует еще 10 файлов)

Вопрос

Ответьте на любое из следующих вопросов

  • Есть ли простой трюк, и действительно ли это можно сделать (без стрификации)?
  • Возможно, он мутирует foo для хранения некоторой строки на нем, а затем использует это как ключ?
  • Что-то еще и, возможно, я неправильно читаю документы?

Ответ 1

На ум приходят два способа. Во-первых, очевидно, вы можете иметь массив ключей и искать его линейно:

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>")

Ответ 2

Трюк заключается в том, чтобы хранить в массиве и выполнять поиск в O (n) времени путем итерации и использования строгого сравнения - вместо использования истинной хеш-функции, которая была бы поиском O (1). Например, рассмотрим следующее:

var myObj = {};

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

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

Вот моя реализация из другого ответа: Javascript HashTable использует ключ объекта

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)];
        }
    };
}