Чистий об'єкт без prototype
У JavaScript "чистий об'єкт" (або object dictionary) -
це об'єкт без прототипу, тобто без Object.prototype і всіх його вбудованих методів (toString, hasOwnProperty, і т.д.).
Такий об'єкт ідеально підходить для чистих сховищ даних (словники, мапи), де ти хочеш бути впевненим, що жодні вбудовані властивості не перетнуться з твоїми ключами.
Як створити чистий об'єкт
Найпростіший і правильний спосіб
const obj = Object.create(null);Це створює об'єкт без прототипу,
тобто obj.__proto__ === undefined і Object.getPrototypeOf(obj) === null.
Перевіримо
const obj = Object.create(null);
console.log(Object.getPrototypeOf(obj)); // null
console.log('__proto__' in obj); // false
console.log(typeof obj.toString); // undefinedУ такого об'єкта немає ланцюжка наслідування -
він не наслідує навіть від Object.prototype.
Чому це корисно
Звичайні об'єкти наслідують купу вбудованих методів:
const normal = {};
console.log(Object.getPrototypeOf(normal) === Object.prototype); // true
// Ці методи доступні
console.log(normal.hasOwnProperty); // [Function]
console.log(normal.toString); // [Function]Це може бути небезпечно, якщо ключі перетинаються з цими іменами:
const map = {};
map.toString = 'значення'; // може зламати код, якщо хтось викличе map.toString()"Чистий об'єкт" вирішує цю проблему:
const map = Object.create(null);
map.toString = 'значення'; // просто ключ
console.log(map.toString); // "значення"Приклад використання - "словники" або "мапи"
const dict = Object.create(null);
dict.apple = 1;
dict.banana = 2;
dict['__proto__'] = 3; // безпечно, не впливає на прототип
console.log(dict.apple); // 1
console.log(dict['__proto__']); // 3У звичайних об'єктах __proto__ має особливу поведінку,
але тут - просто звичайна властивість.
Недолік
У "чистого" об'єкта немає вбудованих методів:
const obj = Object.create(null);
obj.name = 'Alice';
console.log(obj.hasOwnProperty('name')); // Помилка: hasOwnProperty is not a functionЯкщо потрібно перевірити наявність властивості, використовуй безпечний спосіб:
console.log(Object.prototype.hasOwnProperty.call(obj, 'name')); // trueАльтернатива - використовувати Map
Сучасний спосіб зберігати словники:
const map = new Map();
map.set('apple', 1);
map.set('__proto__', 2);
console.log(map.get('__proto__')); // 2Map вирішує ту саму задачу,
але зберігає дані з будь-якими ключами (в тому числі об'єктами).
ПІДСУМОК
| Спосіб | Прототип | Доступ до вбудованих методів | Підходить для словників |
|---|---|---|---|
{} | Object.prototype | Є (toString, hasOwnProperty) | Ні |
Object.create(null) | null | Немає | Так |
new Map() | не об'єкт | Методи set, get, has | Так (сучасний варіант) |
В одній фразі:
Щоб створити "чистий об'єкт" без
Object.prototype, використовуйjavascriptconst obj = Object.create(null);
- він не наслідує нічого, і ідеально підходить для безпечних словників.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.