#javascript
С сервера приходит "разреженный" json вида
[
{ a: 1, b: 2 },
{ a: 2, c: 3 },
{ b: 2, c: 3 }
]
т.е. массив объектов, в каждом из которых могут быть свойства a, b, c. Список свойств
заранее известен, и он достаточно большой (около 40 штук).
Заполненность каждого элемента достаточно малая (2-3 свойства).
Выражение
data[0].c
возвращает undefined. Нужет какой-то способ заставить его возвращать null (т.к. есть
куча уже написанного кода, который ожидает именно null).
Желательно решение, работающее в IE8+.
__defineGetter__ умер не родившись, Harmony Proxy не поддерживается до Edge.
Писать некрасивый код, который шел бы по списку объектов и выставлял все 40 свойств
у каждого в null не хотелось бы.
UP: речь идет не о каком-то хитром хаке ради замены семантики undefined на null во
всем приложении. Цель - сэкономить на сериализации, чтобы избежать передачи пачки бесполезных
данных с сервера. Потому что никакая семантика не оправдывает передачу
{ a: 1, b: 2, x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
x : null, x : null, x : null, x : null, x : null,
},
вместо { a: 1, b: 2 }. Сервер знает о существовании свойства, и о том, что оно -
null, клиент знает о существовании свойства, и о том, что оно null. Соответственно,
"переписать" - не решение.
Ответы
Ответ 1
Можно попытаться использовать решение на базе прототипов. Основная идея -- установить в качестве прототипа каждого из передаваемых объектов объект, содержащий значения по умолчанию (те самые поля с null). Раз нужна поддержка IE8+, то решения на базе Object.create, Object.setPrototypeOf и __proto__ не будут работать без полифилов. Зато, можно использовать обычную функцию-конструктор и не боятся за кроссбраузерность. Вот пример реализации: var ObjWrapper = function(obj) { // Поскольку объект разреженный, этот цикл будет иметь // небольшое число итераций. for (var i in obj) { if (!obj.hasOwnProperty(i)) { continue; } this[i] = obj[i]; } }; // Мы можем использовать всего ОДИН объект в качестве прототипа. // Это позволяет экономить память, не занимая ее кучей null-свойств // каждого обернутого объекта. ObjWrapper.prototype = { a: null, b: null, c: null, d: null, e: null // Задание null-свойств можно оптимизировать с использованием цикла, // хотя это уже детали. }; var obj = new ObjWrapper({a: 'test'}); console.log(obj.c); // выведет null вместо undefined При использовании такого подхода нужно иметь в виду два момента: Конструкция obj.hasOwnProperty('d') выдаст false, если оборачиваемый объект не имеет свойства d. В ряде случаев это может быть критичным. Все равно придется использовать цикл, при десериализации массива и оборачивать каждый его элемент.Ответ 2
есть куча уже написанного кода, который ожидает именно null Переписать. Потому что undefined == null не просто так.
Комментариев нет:
Отправить комментарий