Видалення власності в JavaScript
На цій сторінці представлено багато різних варіантів не тому, що більшість варіантів є неправильними, або тому, що відповіді є дублікатами, а тому, що відповідна методика залежить від ситуації, в якій ви знаходитесь, та цілей завдань, які ви та / або ви команда намагається виконати. Щоб відповісти на запитання однозначно, потрібно знати:
- Версія ECMAScript, на яку ви орієнтовані
- Діапазон типів об'єктів, на яких потрібно видалити властивості, та тип імен властивостей, які потрібно мати, щоб опустити (Тільки рядки? Символи? Слабкі посилання, відображені з довільних об’єктів? Все це були типи покажчиків властивостей у JavaScript вже протягом багатьох років )
- Етокси / схеми програмування, які ви та ваша команда використовуєте. Ви віддаєте перевагу функціональним підходам, і мутація є багатослівною у вашій команді, або ви використовуєте мутативні об'єктно-орієнтовані методи дикого заходу?
- Ви хочете досягти цього в чистому JavaScript або ви готові та можете використовувати сторонню бібліотеку?
Після того, як відповіли на ці чотири запити, у JavaScript існує фактично чотири категорії "видалення власності", з яких можна вибрати, щоб відповідати вашим цілям. Вони є:
Видалення властивості мутативного об'єкта, небезпечно
Ця категорія призначена для роботи з об'єктними літералами чи об'єктами, коли ви хочете зберегти / продовжити використовувати оригінальну посилання та не використовуєте функціональні принципи без стану у своєму коді. Приклад синтаксису в цій категорії:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws
Ця категорія - найдавніша, найпростіша та найбільш підтримувана категорія видалення майна. Він підтримує Symbol
та індекси масивів на додаток до рядків та працює у будь-якій версії JavaScript, за винятком першої версії. Однак, це мутація, яка порушує деякі принципи програмування та має наслідки для продуктивності. Це також може призвести до вимкнутих винятків при використанні неконфігуруваних властивостей у суворому режимі .
Опущення властивості рядка на основі відпочинку
Ця категорія призначена для роботи в екземплярах простого об'єкта або масиву в новіших смаках ECMAScript, коли потрібен немутативний підхід і вам не потрібно обліковувати клавіші Symbol:
const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(
Видалення властивості мутативного об'єкта, безпечно
Ця категорія призначена для роботи з об'єктними літералами або об'єктами, коли ви хочете зберегти / продовжувати використовувати оригінальну посилання, захищаючи від винятків, перекинутих на неконфігурувані властивості:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false
Крім того, хоча мутація об'єктів на місці не є без громадянства, ви можете використовувати функціональний характер, Reflect.deleteProperty
щоб зробити часткове застосування та інші функціональні методи, які неможливі з delete
операторами.
Опущення властивості рядка на основі синтаксису
Ця категорія призначена для роботи в екземплярах простого об'єкта або масиву в новіших смаках ECMAScript, коли потрібен немутативний підхід і вам не потрібно обліковувати клавіші Symbol:
const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(
Бездіяльність власності на основі бібліотеки
Ця категорія, як правило, дозволяє забезпечити більшу функціональну гнучкість, включаючи облік символів та опущення більше одного властивості в одному виписці:
const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"