Составление ключей к карте ES6, состоящей как из примитивов, так и из объектов

ES6 Maps позволяет использовать ключи с любым значением, включая функции, объекты и любые примитивы. Я хочу создать комбинированный ключ со строкой и ссылкой на DOM-узел.

var map = new Map();
var myKey = document.body + 'my string'

map.set(myKey, 'my value')

Очевидно, это не сработает, добавление выше будет оценивать [object HTMLBodyElement]my string. Как бы я это сделал?

На вашем месте я бы дал идентификатор элементу HTML и использовал бы объединение идентификатора и your string для получения уникального ключа!

sjahan 29.06.2018 16:17

@sjahan Я хотел бы использовать функцию карт ES6 для использования объектов в качестве ключей, и я должен иметь возможность делать это с любым элементом.

user1506145 29.06.2018 16:21

@ user1506145 Вы также не можете комбинировать объект со строкой. И обратите внимание, что объекты как ключи по-прежнему сравниваются по идентичности, а не по какой-либо эквивалентности.

Bergi 29.06.2018 16:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
76
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете делать то, что буквально описали, но у вас может быть карта с картами. Я бы, вероятно, использовал WeakMap с ключом по ссылке DOM (чтобы он не заставлял элемент оставаться в памяти, если он удаляется манипуляциями с DOM), где значение - Map с ключом соответствующей строки. Например.:

let entriesByElement = new WeakMap();

Установка элемента:

let map = entriesByElement.get(document.body);
if (!map) {
    map = new Map();
    entriesByElement.set(document.body, map);
}
map.set(keyString, value);

Получение элемента:

let map = entriesByElement.get(document.body);
let value = map && map.get(keyString);

(В этом примере предполагается, что у вас не будет undefined в качестве допустимого сохраненного значения.)

Вы можете завершить это в классе.

Пример:

class ExampleStore {
    constructor() {
        this.entriesByElement = new WeakMap();
    }
    set(element, string, value) {
        let map = this.entriesByElement.get(element);
        if (!map) {
            map = new Map();
            this.entriesByElement.set(element, map);
        }
        map.set(string, value);
    }
    get(element, string) {
        const map = this.entriesByElement.get(element);
        return map && map.get(string);
    }
}

const store = new ExampleStore();

let div1 = document.getElementById("one");
let div2 = document.getElementById("two");

store.set(div1, "a", "ayy");
store.set(div1, "b", "bee");

store.set(div2, "a", "alpha");

console.info(store.get(div1, "a")); // "ayy"
console.info(store.get(div1, "b")); // "bee"

console.info(store.get(div2, "a")); // "alpha"
console.info(store.get(div2, "b")); // undefined (doesn't have that entry)

// Removing div1
document.body.removeChild(div1);
div1 = null;

console.info(store.get(div1, "a")); // May be undefined, if the element has been
                                   // cleaned up (it is for me on Chrome,
                                   // Firefox and Edge), since we're using a
                                   // WeakMap.
<div id = "one"></div>
<div id = "two"></div>

Что бы я сказал.

Bergi 29.06.2018 16:21

Используя этот пользовательский MultiKeyMap, вы можете создать карту, которая принимает любые цифровые ключи на основе номера, который вы передали в constructor при его создании. Однако обратите внимание, что кортеж ключей - упорядоченный:

class MultiKeyMap extends Map {
  constructor (keys = 1) {
    if (keys < 1) {
      throw new RangeError('keys must be greater than 0')
    }

    // 1 key is just a normal Map
    if (keys === 1) {
      return new Map()
    }

    super()
    this.keys = keys
  }
  
  get (key, ...keys) {
    if (arguments.length !== this.keys) {
      throw new RangeError('Unexpected number of keys')
    }

    // return early
    if (!super.has(key)) {
      return undefined
    }

    return super.get(key).get(...keys)
  }

  // (...keys, value) is an illegal signature
  set (key, ...args) {
    if (args.length !== this.keys) {
      throw new RangeError('Unexpected number of keys')
    }

    if (!super.has(key)) {
      super.set(key, new MultiKeyMap(this.keys - 1))
    }

    return super.get(key).set(...args)
  }
  
  has (key, ...keys) {
    if (arguments.length !== this.keys) {
      throw new RangeError('Unexpected number of keys')
    }

    return super.has(key) && super.get(key).has(...keys)
  }
}

const map = new MultiKeyMap(2)

map.set(document.body, 'my string', 'my value')

console.info(`document.body, 'my string'`)
console.info(map.has(document.body, 'my string'))
console.info(map.get(document.body, 'my string'))
console.info(`'my string', document.body`)
console.info(map.has('my string', document.body))
console.info(map.get('my string', document.body))

Другие вопросы по теме