Comments 26
Лень проверять, но всё же: стандартный Map (ECMAScript 2016, но вроде уже давно есть во всех браузерах) проблему не решает?
UFO just landed and posted this here
Действительно, отсутствие прототипа помогает. Но нельзя делать вот так, например.
newMap = {...oldMap1, 'newKey': 'newValue' }
Кстати в lodash метод _.groupBy тоже этому подвержен.
Насчет Map — честно говоря, сейчас не помню почему ещё мне не захотелось вызывать методы get и set.
newMap = {...oldMap1, 'newKey': 'newValue' }
Кстати в lodash метод _.groupBy тоже этому подвержен.
Насчет Map — честно говоря, сейчас не помню почему ещё мне не захотелось вызывать методы get и set.
Вспомнил. Cейчас же неделя react vs vue vs angular. В redux есть одно неочевидное требование. Объекты, которые возвращает редюсер должны быть сериализуемы.
Если мы захотим сохранить состояние для последующего восстановления и использования, то в случе Map, после сериализации-десериализации будем иметь не тоже самое, что было до. Это же касается и объекта без прототипа.
Если мы захотим сохранить состояние для последующего восстановления и использования, то в случе Map, после сериализации-десериализации будем иметь не тоже самое, что было до. Это же касается и объекта без прототипа.
Немного подумал, написал вот такой тест. Оказалось, что падает
починил, не смог определить, это breaking change или нет. У меня, по крайней мере ничего не сломалось
it('should return no value for prototype property after serialize/deserialize action', async function (): Promise<void> {
// arrange
const map = stringMap();
// act
const deserialized = JSON.parse(JSON.stringify(map));
const ctor = deserialized['constructor'];
// assert
expect(noValue(ctor)).to.be.equal(true);
});
починил, не смог определить, это breaking change или нет. У меня, по крайней мере ничего не сломалось
А для новичков — что за тестовый Фреймворк и где почитать*
У редакса вообще много проблем с (де)сериализацией. Даже не надо такой экзотики как Map, достаточно вспомнить Date. При сериализации он становится строкой и строкой же десериализуется. И есть вполне рабочие методы избежать этого, которые, думается, можно применить и в вашем случае.
Хм, а тупо препендить что-то к ключу, чтобы не натыкаться на зарезервированные слова, это типа костыль и криво выглядит?
UFO just landed and posted this here
Вместо
const a = {};
нужно использовать const a = Object.create(null);
, если очень хочется реализовать структуру MapОни, конечно, применимы и даже необходимы, если в качестве ключа нужно использовать объект, а не строку или число.
Не совсем так: ключами объекта могут быть ТОЛЬКО строки. Если использовать число в качестве ключа объекта, оно будет преобразовано в строку.
ну т.е. смысл статьи в том, что если у вас в ключах могут оказаться «зарезервированные слова» (присутствующие в Object.prototype), то подумайте о том, чтобы не использовать Object?
hasOwnProperty! не?
let b = a.hasOwnProperty(key)? a[key] || 'defaultValue': 'defaultValue';
let b = a.hasOwnProperty(key)? a[key] || 'defaultValue': 'defaultValue';
Если вам, как вы указали выше, важно чтобы Object.Prototype объекта был не null (для redux), то почему бы не написать собственный getter, который бы выглядел как-то так:
Таким образом вы оставите только те свойства объекта, которые принадлежат именно ему, т.е. для вашего map — только добавленные свойства
function get(object, key){
return object.hasOwnProperty(key) ? object[key] : undefined
}
Таким образом вы оставите только те свойства объекта, которые принадлежат именно ему, т.е. для вашего map — только добавленные свойства
Меня не прототип null не устраивает, а то что это свойство теряется после некоторых операций. Но честно скажу не знал о возможности создавать объекты без прототипа, может бы и не стал заморачиваться с велосипедостроением.
Геттер с этой проверкой тоже один из вариантов решения, почему нет. Одиночный оверхед во время создания против постоянного оверхеда при работе с объектом.
Геттер с этой проверкой тоже один из вариантов решения, почему нет. Одиночный оверхед во время создания против постоянного оверхеда при работе с объектом.
Так есть же Map и WeakMap в ES6
Sign up to leave a comment.
Еще один нюанс JavaScript, о котором все знают, но не все задумываются